C++(18):命名空间
多个库将名字放置在全局命名空间中将引发命名空间污染。
命名空间可以用来防止名字冲突,它分割了全局命名空间,其中每个命名空间是一个作用域。通过在某个命名空间中定义库的名字,库的作者(以及用户)可以避免全局名字固有的限制。
命名空间定义
一个命名空间的定义包含两部分:关键字namespace + 命名空间名字。
在命名空间名字后面是一系列由花括号括起来的声明和定义。只要能出现在全局作用域中的声明就能置于命名空间内,主要包括:类、变量(及其初始化操作)、函数(及其定义)、模板和其他命名空间。
namespace cplusplus_primer{class Sales_data{/*...*/};
} //无须分号
命名空间的名字也必须在定义它的作用域内保持唯一。
命名空间既可以定义在全局作用域内,也可以定义在其他命名空间中,但是不能定义在函数或类的内部。
命名空间作用域后面无须分号。
每个命名空间都是一个作用域
命名空间中的每个名字都必须表示该空间内的唯一实体:不同命名空间的作用域不同,所以在不同命名空间内可以有相同名字的成员。
定义在某个命名空间中的名字可以被该命名空间内的其他成员直接访问,也可以被这些成员内嵌作用域中的任何单位访问。位于该命名空间之外的代码则必须明确指出所用的名字属于哪个命名空间。
cplusplus_primer::Query q = cplusplus_primer::Query("hello")
命名空间可以不是连续的
//命名空间定义
namespace nsp{//相关声明
}
命名空间可以定义在几个不同的部分。
命名空间的一部分成员的作用是定义类,以及声明作为类接口的函数及对象,则这些成员应该置于头文件中,这些头文件将被包含在使用了这些成员的文件中。
命名空间成员的定义部分则置于另外的源文件中。
定义多个类型不相关的命名空间应该使用单独的文件分别表示每个类型(或关联类型构成的集合)。
定义命名空间成员
假定作用域中存在合适的声明语句,则命名空间中的代码可以使用同一命名空间定义的名字的简写形式。
#include "Sales_data.h"
namespace cplusplus primer{ //重新打开命名空间cplusplus_primer//命名空间中定义的成员可以直接使用名字,此时无须前缀std::istream&operator>>(std::istream& in,Sales_data& s){/* ...* /)}
}
也可以在命名空间定义的外部定义该命名空间的成员。命名空间对于名字的声明必须在作用域内,同时该名字的定义需要明确指出其所属的命名空间:
//命名空间之外定义的成员必须使用含有前缀的名字
cplusplus primer:: Sales_data
cplusplus_primer::operator+(const Sales_data& lhs, const Sales data& rhs){sales_data ret (lhs);// ...
}
模板特例化
模板特例化必须定义在原始模板所属的命名空间中。只要在命名空间中声明了特例化,就可以在命名空间外部定义它了。
全局命名空间
全局作用域中定义的名字(即在所有类、函数及命名空间之外定义的名字)也就是定义在全局命名空间中。
全局命名空间以隐式的方式声明,并且在所有程序中都存在。
全局作用域中定义的名字被隐式地添加到全局命名空间中。
作用域运算符同样可以用于全局作用域成员:
::member_name // 表示全局命名空间中地一个成员
嵌套的命名空间
嵌套的命名空间是指定义在其他命名空间中的命名空间。
内层命名空间声明的名字将隐藏外层命名空间声明的同名成员。在嵌套的命名空间中定义的名字只在内层命名空间中有效,外层命名空间中的代码要想访问它必须在名字前添加限定符。
cplusplus_primer::QueryLib::Query
内联命名空间
和普通的嵌套命名空间不同,内联命名空间中的名字可以被外层命名空间直接使用。
无须在内联命名空间的名字前添加表示该命名空间的前缀,通过外层命名空间的名字就可以直接访问它。
定义内联命名空间的方式是在关键字namespace前添加关键字inline:
inline namespace FifthEd{//该命名空间表示本书第5版的代码
}
namespace FifthEd{ //隐式内联class Query base {/* ...*/};//其他与 Query有关的声明
}
关键字inline必须出现在命名空间第一次定义的地方,后续再打开命名空间的时候可以写inline,也可以不写。
未命名的命名空间
未命名的命名空间是指关键字namespace后紧跟花括号括起来的一系列声明语句。
未命名的命名空间中定义的变量拥有静态生命周期:它们在第一次使用前创建,并且直到程序结束才销毁。
一个未命名的命名空间可以在某个给定的文件内不连续,但是不能跨越多个文件。
如果两个文件都含有未命名的命名空间,则这两个空间相互无关。在这两个未命名的命名空间中可以定义相同的名字,并且这些定义表示的是不同实体。
如果一个头文件定义了未命名的命名空间,则该命名空间中定义的名字将在每个包含了该头文件的文件中对应不同实体。
使用命名空间
命名空间的别名
命名空间的别名可以为命名空间的名字设定一个短得多的同义词。
namespace cplusplus_primer {/* ...*/};
//可以为其设定一个短得多的同义词;
namespace primer = cplusplus_primer;//命名空间的别名也可以指向一个嵌套的命名空间:
namespace Qlib = cplusplus_primer::QueryLib;
Qlib::Query q;
using
一条using声明语句一次只引入命名空间的一个成员。
using的有效范围从using声明的地方开始,一直到using声明所在的作用域结束为止。这有助于减少代码中的冗余,提高可读性。
namespace MyNamespace {int value = 42;void Print() {std::cout << "Hello from MyNamespace" << std::endl;}
}int main() {using MyNamespace::value; // 引入命名空间中的变量using MyNamespace::Print; // 引入命名空间中的函数std::cout << value << std::endl; // 可以直接使用value,不需要MyNamespace::Print(); // 可以直接使用Print,不需要MyNamespace::return 0;
}
using指示以关键字using开始,后面是关键字namespace 以及命名空间的名字。
using 指示不能用在类的作用域内。但是 using 声明是可以的。
using 指示令引入的命名空间成员的作用域提升到包含命名空间本身和 using 指示的最近作用域。可以使用该命名空间内的所有名称,而无需使用限定符。
namespace MyNamespace {int value = 42;void Print() {std::cout << "Hello from MyNamespace" << std::endl;}
}int main() {using namespace MyNamespace; // 引入整个命名空间std::cout << value << std::endl; // 可以直接使用value,不需要MyNamespace::Print(); // 可以直接使用Print,不需要MyNamespace::return 0;
}
头文件如果在其顶层作用域中含有 using 指示或 using 声明,则会将名字注入到所有包含了该头文件的文件中。
因此头文件最多只能在它的函数或命名空间内使用 using 指示或 using 声明。
避免使用 using 指示:一般不要使用 using 指示,很危险。
using 指示的用处:在命名空间本身的实现文件中可以使用 using 指示。
类、命名空间与作用域
对命名空间内部名字的查找遵循常规的查找规则:即由内向外依次查找每个外层作用域。
外层作用域也可能是一个或多个嵌套的命名空间,直到最外层的全局命名空间查找过程终止。只有位于开放的块中且在使用点之前声明的名字才被考虑。
实参相关的查找与类类型形参
实参相关的查找与类类型形参
std::string s;
std::cin >> s;
重载操作符 >> 定义在标准库 string 中,string 定义在命名空间 std 中。但是不用 std:: 限定符就可以调用 >> 操作符。
这是因为:给一个函数传递一个类类型的对象时,除了在常规的作用域查找外还会查找实参类所属的命名空间。
>>操作符的形参(iostream 和 string)是类类型的,所以编译器还会查找 iostream 和 string 所属的命名空间。
查找与 std::move 和 std::forward
move 和 forward 都是模板函数,在标准库的定义中它们都接受一个右值引用的函数形参。在函数模板中,右值引用形参可以匹配任何类型。
如果用户自己也定义了一个 move 函数并且它只接受一个参数,那么必然会与标准库的 move 函数冲突。forward 函数也是如此。所以 move 和 forward 的名字冲突非常频繁,使用时应该写 std::move 和 std::forward。
重载与命名空间
与实参相关的查找与重载
对于接受类类型实参的函数来说,其名字查找将在实参类所属的命名空间中进行。
重载与 using 声明
using 声明语句声明的是一个名字,而非一个特定的函数。当我们为函数书写using声明时,该函数的所有版本都被引入到当前作用域中。
重载与 using 指示
using指示将命名空间的成员提升到外层作用域中,如果命名空间的某个函数与该命名空间所属作用域的函数同名,则命名空间的函数将被添加到重载集合中。
与using声明不同的是,对于using 指示来说,引入一个与已有函数形参列表完全相同的函数并不会产生错误。只需要调用时指明是哪个版本即可。
跨越多个 using 指示的重载
如果存在多个命名空间,则来自每个命名空间的名字都将成为候选函数集的一部分。
相关文章:
C++(18):命名空间
多个库将名字放置在全局命名空间中将引发命名空间污染。 命名空间可以用来防止名字冲突,它分割了全局命名空间,其中每个命名空间是一个作用域。通过在某个命名空间中定义库的名字,库的作者(以及用户)可以避免全局名字…...
K8S最新版本集群部署(v1.28) + 容器引擎Docker部署(上)
温故知新 📚第一章 前言📗背景📗目的📗总体方向 📚第二章 基本环境信息📗机器信息📗软件信息📗部署用户kubernetes 📚第三章 Kubernetes各组件部署📗安装kube…...
生产环境部署与协同开发 Git
目录 一、前言——Git概述 1.1 Git是什么 1.2 为什么要使用Git 什么是版本控制系统 1.3 Git和SVN对比 SVN集中式 Git分布式 1.4 Git工作流程 四个工作区域 工作流程 1.5 Git下载安装 1.6 环境配置 设置用户信息 查看配置信息 二、git基础 2.1 本地初始化仓库 编辑…...
Qt/C++编写视频监控系统80-远程回放视频流
一、前言 远程回放NVR或者服务器上的视频文件,一般有三种方式,第一种是调用厂家的SDK,这个功能最全,但是缺点明显就是每个厂家的设备都有自己的SDK,只兼容自家的设备,如果你的软件需要接入多个厂家的&…...
用于设计和分析具有恒定近心点半径的低推力螺旋轨迹研究(Matlab代码实现)
💥💥💞💞欢迎来到本博客❤️❤️💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 ⛳️座右铭&a…...
MongoDB - 构造复杂查询条件执行查询
文章目录 1. 构造 keyword 的查询条件2. 构造 threatSubType 的查询条件3. 相应的实体类 /*** 查询白名单详情** param offset 第几页开始* param limit 每页显示的最大值* param keyword 模糊搜索值* param order 排序方式(升序/降序…...
如何从ChatGPT中获得最佳聊天对话效果
从了解ChatGPT工作原理开始,然后从互动中学习,这是一位AI研究员的建议。 人们利用ChatGPT来撰写文章、论文、生成文案和计算机代码,或者仅仅作为学习或研究工具。然而,大多数人不了解它的工作原理或它能做什么,所以他…...
深入浅出:手把手教你实现单链表
一、什么是链表 链表是一种链状数据结构。简单来说,要存储的数据在内存中分别独立存放,它们之间通过某种方式相互关联。 如果我们使用C语言来实现链表,需要声明一个结构体作为链表的结点,结点之间使用指针关联。 二、单向链表的结…...
vite 打包项目后访问显示空白页的问题,开发环境正常,生产环境无报错。
有没有可能, 你跟我遇到同样的问题 白屏的写法 const routes [{path: /,component: import(../views/index.vue),} ]正确的写法 const routes [{path: /,component: () > import(../views/index.vue),} ]有时候方向很重要,当在错误的方向上无脑冲…...
打造成功的砍价营销大解析,销量飙升
砍价活动是吸引顾客的一种有效方式,可以帮助提高销量和提升品牌知名度。在乔拓云平台上,我们提供了一套简单易用的工具,让您能够轻松地制作一个成功的砍价活动。下面,我将详细介绍具体步骤,让您能够轻松上手。 第一步&…...
【Flink进阶】- Flink kubernetes operator 常用的命令
目录 1、应用程序管理 (1)提交 Flink 应用程序 (2)查看 Flink 应用程序列表...
ASP.NET Core 的日志系统
ASP.NET Core 提供了丰富日志系统。 可以通过多种途径输出日志,以满足不同的场景,内置的几个日志系统包括: Console,输出到控制台,用于调试,在产品环境可能会影响性能。Debug,输出到 System.Di…...
android13(T) 以太网设置工具类
13 版本的以太网设置和以前版本有所变动,在 AS 中就能直接调用对应 API 将 build.gradle 版本修改 compileSdkVersion 31, 即可直接调用 EthernetManager 相关, 设置静态等方法可以通过反射调用设置。 以下是核心设置静态和动态参数工具类,…...
电脑报错提示xinput1_3.dll缺失怎么办?xinput1_3.dll丢失的简单恢复方案
今天,我将为大家分享一个与我们日常工作息息相关的话题——xinput1_3.dll丢失的4种解决方法。在我们的日常工作和生活中,电脑出现问题是常有的事,而xinput1_3.dll丢失则是其中较为常见的一种问题。那么,什么是xinput1_3.dll?它为…...
unity 之参数类型之引用类型
文章目录 引用类型引用类型与值类型的差异 引用类型 在Unity中,引用类型是指那些在内存中存储对象引用的数据类型。以下是在Unity中常见的引用类型的介绍: 节点(GameObject): 在Unity中,游戏对象ÿ…...
SpringBoot自定义工具类—基于定时器完成文件清理功能
直接复制粘贴既可!! import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; import java.io.File; import java.time.LocalDate; import java.time.LocalDateTime; import java.time.ZoneOff…...
安卓设置混淆后,gson报错解决方法
一,设置开启混淆release {minifyEnabled truezipAlignEnabled trueshrinkResources trueproguardFiles getDefaultProguardFile(proguard-android-optimize.txt), proguard-rules.pro } 二,混淆的文件中,对gson相关类不进行混淆,否…...
WPF实战项目十四(API篇):登录注册接口
1、新建UserDto.cs public class UserDto : BaseDto{private string userName;/// <summary>/// 用户名/// </summary>public string UserName{get { return userName; }set { userName value;OnPropertyChanged(); }}private string account;/// <summary>…...
10个免费PPT下载资源网站分享
PPT超级市场https://pptsupermarket.com/ PPT超级市场是一个完全免费的PPT模板下载网站,不需要注册登录,点击下载就能直接使用。 叮当设计https://www.dingdangsheji.com/ 叮当设计是一个完全免费的PPT模板下载网站,每一套PPT的质量都很高。除…...
SpringCloud入门——微服务调用的方式 RestTemplate的使用 使用nacos的服务名初步(Ribbon负载均衡)
目录 引出微服务之间的调用几种调用方法spring提供的组件 RestTemplate的使用导入依赖生产者模块单个配置的情况多个配置的情况没加.yaml的报错【报错】两个同名配置【细节】 完整代码config配置主启动类controller层 消费者模块进行配置restTemplate配置类controller层 使用na…...
从零实现富文本编辑器#5-编辑器选区模型的状态结构表达
先前我们总结了浏览器选区模型的交互策略,并且实现了基本的选区操作,还调研了自绘选区的实现。那么相对的,我们还需要设计编辑器的选区表达,也可以称为模型选区。编辑器中应用变更时的操作范围,就是以模型选区为基准来…...
【第二十一章 SDIO接口(SDIO)】
第二十一章 SDIO接口 目录 第二十一章 SDIO接口(SDIO) 1 SDIO 主要功能 2 SDIO 总线拓扑 3 SDIO 功能描述 3.1 SDIO 适配器 3.2 SDIOAHB 接口 4 卡功能描述 4.1 卡识别模式 4.2 卡复位 4.3 操作电压范围确认 4.4 卡识别过程 4.5 写数据块 4.6 读数据块 4.7 数据流…...
在 Nginx Stream 层“改写”MQTT ngx_stream_mqtt_filter_module
1、为什么要修改 CONNECT 报文? 多租户隔离:自动为接入设备追加租户前缀,后端按 ClientID 拆分队列。零代码鉴权:将入站用户名替换为 OAuth Access-Token,后端 Broker 统一校验。灰度发布:根据 IP/地理位写…...
跨链模式:多链互操作架构与性能扩展方案
跨链模式:多链互操作架构与性能扩展方案 ——构建下一代区块链互联网的技术基石 一、跨链架构的核心范式演进 1. 分层协议栈:模块化解耦设计 现代跨链系统采用分层协议栈实现灵活扩展(H2Cross架构): 适配层…...
uniapp微信小程序视频实时流+pc端预览方案
方案类型技术实现是否免费优点缺点适用场景延迟范围开发复杂度WebSocket图片帧定时拍照Base64传输✅ 完全免费无需服务器 纯前端实现高延迟高流量 帧率极低个人demo测试 超低频监控500ms-2s⭐⭐RTMP推流TRTC/即构SDK推流❌ 付费方案 (部分有免费额度&#x…...
Android第十三次面试总结(四大 组件基础)
Activity生命周期和四大启动模式详解 一、Activity 生命周期 Activity 的生命周期由一系列回调方法组成,用于管理其创建、可见性、焦点和销毁过程。以下是核心方法及其调用时机: onCreate() 调用时机:Activity 首次创建时调用。…...
排序算法总结(C++)
目录 一、稳定性二、排序算法选择、冒泡、插入排序归并排序随机快速排序堆排序基数排序计数排序 三、总结 一、稳定性 排序算法的稳定性是指:同样大小的样本 **(同样大小的数据)**在排序之后不会改变原始的相对次序。 稳定性对基础类型对象…...
动态 Web 开发技术入门篇
一、HTTP 协议核心 1.1 HTTP 基础 协议全称 :HyperText Transfer Protocol(超文本传输协议) 默认端口 :HTTP 使用 80 端口,HTTPS 使用 443 端口。 请求方法 : GET :用于获取资源,…...
AI语音助手的Python实现
引言 语音助手(如小爱同学、Siri)通过语音识别、自然语言处理(NLP)和语音合成技术,为用户提供直观、高效的交互体验。随着人工智能的普及,Python开发者可以利用开源库和AI模型,快速构建自定义语音助手。本文由浅入深,详细介绍如何使用Python开发AI语音助手,涵盖基础功…...
DBLP数据库是什么?
DBLP(Digital Bibliography & Library Project)Computer Science Bibliography是全球著名的计算机科学出版物的开放书目数据库。DBLP所收录的期刊和会议论文质量较高,数据库文献更新速度很快,很好地反映了国际计算机科学学术研…...
