前言
发现 namespace 这个小细节在工作项目中处理的有一点点小混乱,于是稍微梳理了一下关于 C++ namespace 使用相关的使用内容,为日后项目的重构做准备,虽然是很小的点,但是也是值得注意的,毕竟代码的质量体现在每一个细节中。否则在项目代码中无组织,更容易造成理解上的困难。
Namespace的作用和好处包括:
- 避免命名冲突:通过将代码组织在不同的namespace中,可以避免不同部分的代码使用相同的名称导致的冲突。
- 提高代码的可读性和可维护性:使用namespace可以更清晰地组织代码,帮助开发人员更容易地理解和维护代码。
- 提高代码的可重用性:通过将相关功能或类组织在同一个namespace中,可以更容易地重用这些代码。
- 控制访问权限:可以使用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