C++入门——命名空间

C++入门——命名空间

本期内容,我们正式进入C++专栏。前几期内容中,我们用C语言实现了一些数据结构,包括顺序表,单链表,双向循环链表,栈和队列等等,为C++的学习打下了基础。从现在开始,让我们一起踏上C++的旅程吧!

一、产生背景

在C++标准化之前,也就是1998年之前,程序员在大型项目中经常会遇到名称冲突的问题。比如,不同的库可能定义了相同名称的类或函数,导致编译错误。这时候,开发者通常会用前缀来区分,比如把类命名为MyLib_ClassName,但这种方法会让代码变得冗长且难以维护。随着软件规模扩大,尤其是面向对象编程和模板的广泛使用,代码复用和模块化变得更重要,这时候名称冲突的问题更加突出。命名空间的引入让C++能够更好地支持大型项目,促进库的发展,比如==标准模板库(STL)==的广泛使用。
我们来举一个简单的例子:
示例1
在这里,我们定义了一个全局变量rand,现在要将其打印出来,程序运行目前没有任何问题,接下来,我们include一个头文件<stdlib.h>,结果如图:
示例2
在这里插入图片描述
在这里,我们展开了头文件<stdlib.h>,所谓的展开头文件,就是将头文件中的内容逐字插入源文件,将代码合并,这是预处理的核心操作,在头文件<stdlib.h>中,rand是一个函数,用来生成伪随机数。当头文件展开后,它暴露在了全局域,而在全局域中,我们又定义了一个整型变量rand,二者就产生了冲突。

因此,通过引入命名空间——namespace,我们能够将代码进行逻辑上的隔离,解决命名冲突的问题,其本质就是为代码创建独立的作用域,避免不同模块或库的同名符号相互冲突。命名空间的使用,也让代码更加模块化,同时能够很好地支持大规模的协作开发,不同团队维护独立的命名空间即可。

二、命名空间的使用

1.命名空间的定义

命名空间的定义
在命名空间中,我们可以定义的内容很丰富,比如:变量、函数、结构体、类(以后会讲到)、嵌套命名空间(比如在group中嵌套group_one)……
如图所示:
命名空间示例
同一个工程中允许存在多个相同名称的命名空间,编译器最后会合成同一个命名空间中,例如
新建一个头文件SeqList.h
SeqLIst.h

新建一个头文件Stack.h:
Stack.h
这两个头文件中都是把结构体写在命名空间group中,会和之前写的group里面的内容合并

2.命名空间的使用

我们来看这样一段代码及其运行结果:
示例2
在这里,我们定义了一个全局变量a=1,命名空间group中a=10,main函数中a=100,结果输出的是main函数(局部域)中的a
我们继续往下看:
示例3
这里,我们注释掉了main函数里的a,此时,打印的是全局变量a
接下来,我们把全局变量a也注释掉:
示例4
示例5
这时就出错了,因为在命名空间里的内容需要展开命名空间,或者指定访问命名空间才能使用,有以下三种方式:

(1)展开命名空间——语法为using namespace (命名空间名):

示例6

(2)命名空间名称+域作用限定符——::

示例7
域作用限定符::是C++中用于明确标识符所属作用域的运算符。

(3)使用using将命名空间的某个成员引入

示例8
通过上面的分析,我们知道了访问顺序:局部域->全局域->展开了命名空间域或指定访问命名空间域。

我们来看下面一段代码

示例9
示例10
这里不仅定义了全局变量a,同时也展开了命名空间group,展开命名空间,就将里面的内容暴露在全局域中,因此group中的a就和全局域中的a产生了冲突,正如报错中提到的“a不明确”。

(3)使用命名空间的注意事项

在大型的工程项目中,我们不能使用using namespace将命名空间直接展开,展开会有命名冲突,符号污染等等问题,比如上面的实例就简单地展示了一下产生问题的过程。但是,在我们平时自己写的小型代码文件中可以直接展开命名空间,比如using name space std; 因为平时学习C++写的代码量不大,产生冲突的概率很小,而且展开之后写也是比较方便的。

三、易混点——命名空间、头文件与标准模板库(STL)

三者是不同的,这期内容先简单的聊一聊,以后会逐步讲解,循序渐进。

命名空间(namespace)

作用:逻辑隔离符号,解决全局命名冲突(如 std::vector 与用户自定义 Vector 类);**
STL应用**:标准库所有组件均位于 std 命名空间内。

STL(Standard Template Library)

本质:C++标准库的核心组成部分,包含容器、算法、迭代器等泛型编程组件
实现载体:通过头文件(如 , )提供接口与实现;
依赖关系:STL的实现代码被封装在 std 命名空间中。

头文件(Header File)

角色:代码复用的物理载体,包含函数声明、类定义、模板实现等;
STL关联:所有STL组件需通过包含对应头文件引入(如 #include );
工程意义:头文件是命名空间和STL组件的载体传输的通道。

展开命名空间(Using Directive)

核心行为:通过 using namespace (命名空间名称) 将指定命名空间的所有符号引入当前作用域,允许直接访问这些符号而无需前缀。
作用阶段:发生在编译期的符号解析阶段,影响编译器查找名称的规则。

展开头文件(Include Directive)

核心行为:通过 #include <xxx.h> 将头文件的全部内容逐字复制到当前文件,包括函数声明、类定义、宏等。
作用阶段:发生在预处理阶段,是物理上的代码文本合并。

三、本期总结+下期预告

本期内容是C++入门,讨论了命名空间的产生背景以及使用方法,注意事项等,下期内容将为大家带来输入输出,函数重载等等。

感谢大家的关注,我们下期再见!
在这里插入图片描述

### RAG技术的工作原理 RAG(Retrieval-Augmented Generation)是一种结合检索和生成的技术框架,旨在提升自然语言处理任务中的性能。其核心思想是通过引入外部知识源,在生成过程中增强模型的表现力[^1]。 #### 背景概念 RAG核心在于将传统的纯生成模式转变为一种混合模式——即先从外部知识库中检索相关信息,再基于这些信息生成最终的结果。这种方法能够有效缓解传统生成模型可能存在的幻觉问题(hallucination),并提高生成内容的相关性和准确性[^2]。 #### 实现步骤详解 以下是RAG技术的主要实现过程: 1. **调用大语言模型** 使用预训练的大规模语言模型(如ChatGPT、GLM等)作为基础架构,负责后续的文本生成任务。这一阶段通常依赖于强大的上下文理解能力以及高效的参数化结构。 2. **读取知识库数据** 构建或接入一个大规模的知识库,该知识库可以是以文档形式存储的数据集或者经过加工后的语料集合。此部分决定了可被检索的信息范围及其质量[^3]。 3. **文本索引答案检索** 对知识库内的文本进行预处理,并建立高效查询机制以便快速定位相关内容片段。常见的方法包括倒排索引等技术手段。 4. **文本嵌入向量检索** 将输入问题转化为高维空间中的表示向量,并计算它其他已知样本之间的相似度得分;随后依据得分选取最接近的一组候选对象作为潜在匹配项。 5. **文本多路召回重排序** 经过多轮筛选后得到多个备选方案,进一步采用机器学习算法对其进行综合评估打分,最终选出最优解路径。 6. **文本问答Prompt优化** 针对具体应用场景设计合理的提示模板(Prompt Engineering),引导LLMs按照预期方向完成指定操作,比如精确回答特定领域的问题等等。 ```python import numpy as np def rag_pipeline(question, knowledge_base): """ A simplified example of the RAG pipeline. Args: question (str): The input query from user. knowledge_base (list): List of documents or passages to search through. Returns: str: Generated answer based on retrieved information. """ # Step 1: Embedding and Retrieval embeddings = generate_embeddings([question] + knowledge_base) scores = compute_similarity(embeddings[0], embeddings[1:]) top_k_indices = np.argsort(scores)[-3:] # Top-3 relevant docs # Step 2: Generate Answer with Retrieved Contexts context = "\n".join([knowledge_base[i] for i in top_k_indices]) prompt = f"Question: {question}\nContext:\n{context}" generated_answer = call_large_language_model(prompt) return generated_answer def generate_embeddings(texts): pass # Placeholder function; implement embedding generation here. def compute_similarity(query_embedding, doc_embeddings): pass # Placeholder function; calculate cosine similarity between vectors. def call_large_language_model(prompt): pass # Placeholder function; invoke LLM API using provided prompts. ``` 上述代码展示了简化版的RAG流水线逻辑,实际应用中还需要考虑更多细节和技术挑战。 ---
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值