不必要地使用未命名的命名空间C++
Unnecessary use of unnamed namespaces C++
我在公司里到处都能看到这样的代码:
namespace {
const MAX_LIMIT = 50;
const std::string TOKEN = "Token";
}
我很困惑你为什么需要一个匿名的命名空间。一方面,您需要MAX_LIMIT
和TOKEN
的本地翻译单元。但是由于const
,在没有匿名名称空间的情况下已经实现了这一点。CCD_ 4和简单CCD_。
另一方面,如果文件中的某个地方有一个名称相同的变量,则不会出现命名冲突。
int foo()
{
std::string TOKEN = "MyToken"; // Clash! ::TOKEN vs TOKEN can be used.
}
这将证明匿名命名空间的合理性。但是,您在函数中需要一个变量名的频率是多少?该变量名实际上已经由函数外声明的const
变量使用了?我的答案是永远不会。因此,在实践中,对我来说,不需要未命名的名称空间。有什么提示吗?
namespace
是多余的。您可以删除namespace {
和匹配的}
。
一个区别是,您可以有不同的名称::TOKEN
和unnamed_namespace::TOKEN
。但这可能只是增加了混乱,最好是得到一个编译错误。
不确定您文章的后半部分是关于什么的,局部变量TOKEN
同时隐藏了::TOKEN
和unnamed_namespace::TOKEN
。因此,这一变化对这种情况没有任何影响。
在这种特殊情况下,命名空间确实是多余的,因为默认情况下,const命名空间范围变量确实具有内部链接。
考虑以后更改代码的可能性。也许其中一个变量不应该是const。但将其设为非常量也会更改默认链接。即使在这样的更改之后,匿名命名空间也会保持内部链接。换句话说,anon命名空间将对常量和链接的关注分开。这是否是一件好事,取决于具体情况。
注意,使用static
关键字也可以实现同样的效果。由于这与anon名称空间具有完全相同的效果,因此选择大多是美学的,因此是基于意见的。
使用anon命名空间而不是static
的一个参数可能是一致性。不能使用static
定义具有内部链接的类型。由于某些内部符号(类型)不能在匿名命名空间之外定义,因此可以使用约定在匿名命名空间中定义所有内部符号。当然,这种惯例——就像惯例通常一样——是一个品味问题。
你的第二个反驳似乎是反对一个根本不存在的差异。匿名命名空间与隐藏在函数范围内的名称没有区别。
可以说它提高了清晰度。拥有一个匿名名称空间更清楚地表明,"这段代码只是这个编译单元的实现细节,而不是作为单元接口的一部分"。因为无论如何都必须以这种方式为本地类或结构使用匿名名称空间(没有其他方法来本地化它们),所以以这种方式封装所有本地构造是合理的。
- 命名空间中具有.h和.cpp文件的类
- 从父命名空间重载类型
- 在命名空间中定义函数还是限定函数
- C++:对不存在的命名空间使用命名空间指令
- 通过继承类使用来自不同命名空间的运算符
- 使用命名空间时出现多个定义错误
- CUDA内核和数学函数的显式命名空间
- 嵌套的匿名命名空间
- CMakeLists.txt中的命名空间表示法
- 类是C++中的命名空间吗
- 在命名空间中使用全局命名空间中的函数
- 如何使 std::sort 在 std::swap 和我的命名空间的模板化交换之间没有名称冲突?
- '使用命名空间{嵌套在另一个命名空间中的某个命名空间}"
- 是否可以将函数导入命名空间,但不能导出它?
- C++ C++类中的命名空间降级
- 如何使用 soong 命名空间来有条件地编译模块
- 使用 Clang++ 有没有办法将文件作为命名空间等包含?
- 使用 make 编译 MPI,几个命名空间错误,例如"错误:未知类型名称'使用'?
- 如何通过命名空间调用非静态方法
- 在命名空间名称之前加上 :: 是什么意思?