C++ namespace 使用梳理

本文探讨了C++中namespace的重要性和使用,如何避免命名冲突,以及在ONNX、PyTorch、TVM和MLIR等开源框架中namespace的组织策略。还提及了匿名namespace和implementationdetail的概念。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前言

发现 namespace 这个小细节在工作项目中处理的有一点点小混乱,于是稍微梳理了一下关于 C++ namespace 使用相关的使用内容,为日后项目的重构做准备,虽然是很小的点,但是也是值得注意的,毕竟代码的质量体现在每一个细节中。否则在项目代码中无组织,更容易造成理解上的困难。

Namespace的作用和好处包括:

  1. 避免命名冲突:通过将代码组织在不同的namespace中,可以避免不同部分的代码使用相同的名称导致的冲突。
  2. 提高代码的可读性和可维护性:使用namespace可以更清晰地组织代码,帮助开发人员更容易地理解和维护代码。
  3. 提高代码的可重用性:通过将相关功能或类组织在同一个namespace中,可以更容易地重用这些代码。
  4. 控制访问权限:可以使用namespace来限制对代码的访问权限,从而提高代码的安全性。

对于一些开源代码,针对不同目的有不同地使用方式。

ONNX 源码

简单一点的,就是例如 ONNX 项目,所有代码的 C 文件,通篇使用统一地 namespace ONNX_NAMESPACE {

}

达到一定地避免冲突目的即可。

PyTorch 源码

Pytorch 源码中,因为功能更复杂,模块更多,则是根据模块进行了 namespace 的划分:

请添加图片描述

例如上图文件结构,对应文件夹目录,每个目录中的 namespace 分别为:torch::jit ; torch::lazy ; torch::maps;torch::onnx 等。

TVM 源码

TVM 类似。也是主要根据目录来。有 tvm::relax; tvm::te; tvm::tir 等 namespace 划分。

MLIR 源码

当然还有另一种形式,例如 LLVM 中的 MLIR 模块,根据主要功能性也分成 mlir::detail; mlir::query; 并且没有严格按照目录来,而是以模块实现的功能为主。

请添加图片描述

然后一种新的写法,在 .cpp 文件中:

using namespace XXX;

就可以不用在文件头尾写 花括号了,数量上至少可以少些一行代码。 不过如果有新增的辅助类,相关声明不要忘记还是需要包一层的。例子如下:

mlir\lib\Pass\PassCrashRecovery.cpp

请添加图片描述

新定义了 RecoveryReproducerContext 结构体,然后在结构体外进行定义。

当然每个软件站有自己的实现方式,这里仅采样 4 个开源框架作为参考。

扩展阅读

关于匿名 namespace:
c++ - What effect does an unnamed namespace have on a class? - Stack Overflow

关于 detail 等常见命名含义:
If it’s an implementation detail then name doesn’t matter at all if you’re consistent across your library (and this will help you, not your library users). As you don’t care (from an outside point of view) how private variables are named (in fact there are tons of conventions for that). detail, internal, implementation, impl, core…what you want

C++是一种面向对象的编程语言,是C语言的扩展版本。以下是杜茂康版C++基本语法的梳理: 1.注释: 单行注释:以 // 开头,注释内容直到行末。 多行注释:以 /* 开头,以 */ 结尾,注释内容在两个符号之间。 2.头文件: 头文件包含了程序中需要使用的库和函数声明。 #include <iostream>:包含输入输出流库。 #include <string>:包含字符串操作库。 3.命名空间: 命名空间是一个用来区分不同库中相同名称的函数、类、变量等标识符的方法。 使用命名空间的格式为:namespace namespace_name { ... },例如:namespace std { ... }。 4.基本数据类型: 整型:int, short, long, long long。 浮点型:float, double, long double。 字符型:char。 布尔型:bool。 5.变量: 变量是指程序中可操作的数据存储空间。 变量的定义格式为:数据类型 变量名 = 变量值;,例如:int a = 1;。 6.运算符: 算术运算符:+,-,*,/,%。 关系运算符:==,!=,<,>,<=,>=。 逻辑运算符:&&,||,!。 位运算符:&,|,^,~,<<,>>。 赋值运算符:=,+=,-=,*=,/=,%=,<<=,>>=,&=,^=,|=。 7.流输入输出: cin:从控制台读取输入。 cout:向控制台输出。 格式为:cout << 输出内容;或者 cin >> 输入变量; 8.条件语句: if...else...语句:if (条件) { ... } else { ... }。 switch...case...语句:switch (条件) { case 值1: ... break; case 值2: ... break; ... default: ... }。 9.循环语句: for循环:for (初始化; 条件; 更新) { ... }。 while循环:while (条件) { ... }。 do...while循环:do { ... } while (条件)。 10.函数: 函数是一段完成特定任务的代码块。 函数的定义格式为:返回类型 函数名 (参数列表) { ... }。 调用函数的格式为:函数名 (参数列表)。 11.数组: 数组是一组相同类型的数据元素的集合。 数组的定义格式为:数据类型 数组名[数组大小] = {元素1, 元素2, ...}。 访问数组的元素格式为:数组名[下标]。 12.指针: 指针是一个变量,其值为另一个变量的地址。 指针的定义格式为:数据类型 *指针变量名;。 指针访问变量的格式为:*指针变量名。 13.类: 类是一种用户自定义的数据类型,包含数据和代码。 类的定义格式为:class 类名 { public: 成员变量; 成员函数; private: 私有成员变量; 私有成员函数; protected: 受保护成员变量; 受保护成员函数; }。 14.构造函数和析构函数: 构造函数是一种特殊的函数,在创建对象时自动执行。 析构函数也是一种特殊的函数,在销毁对象时自动执行。 构造函数的格式为:类名 (参数列表) { ... }。 析构函数的格式为:~类名() { ... }。 以上是杜茂康版C++基本语法的梳理,希望能对你有所帮助。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值