不必要地使用未命名的命名空间 C++
Unnecessary use of unnamed namespaces C++
我在公司到处都能看到这样的代码:
namespace {
const MAX_LIMIT = 50;
const std::string TOKEN = "Token";
}
我很困惑为什么你需要一个匿名命名空间。一方面,您需要 MAX_LIMIT
和 TOKEN
的本地翻译单元。但是由于const
,这已经在没有匿名命名空间的情况下实现了。 static const
和简单的const
都实现了本地翻译单元
另一方面,如果您的文件中某处有一个名称相同的变量,则不会发生命名冲突。
int foo()
{
std::string TOKEN = "MyToken"; // Clash! ::TOKEN vs TOKEN can be used.
}
这将证明匿名命名空间的合理性。但是,您多久需要在函数中使用一个实际上已经被在函数外部声明的 const
变量使用的变量名?我的回答是永远不会。所以在实践中,对我来说不需要未命名的命名空间。有什么提示吗?
正如您所解释的,namespace
是多余的。您可以删除 namespace {
并匹配 }
.
一个区别是您可以使用不同的名称 ::TOKEN
和 unnamed_namespace::TOKEN
。但这可能只会增加混乱,最好得到一个编译错误。
不确定 post 的后半部分是关于什么的,局部变量 TOKEN
隐藏了 ::TOKEN
和 unnamed_namespace::TOKEN
。因此,更改对这种情况没有影响。
在这种特殊情况下,命名空间确实是多余的,因为 const 命名空间作用域变量在默认情况下确实具有内部链接。
考虑以后更改代码的可能性。也许其中一个变量毕竟不应该是 const 。但使其成为非常量也会改变默认链接。即使在这样的更改之后,匿名名称空间仍将保持内部链接。换句话说,anon 命名空间分离了对常量性和链接的关注。这是否是一件好事,取决于上下文。
请注意,使用 static
关键字可以实现相同的目的。由于这与 anon 命名空间具有完全相同的效果,因此选择主要是审美,因此基于意见。
使用匿名命名空间而不是 static
的一个论据可能是一致性。您不能使用 static
定义具有内部链接的类型。由于某些内部符号(类型)不能在匿名命名空间之外定义,因此您可以约定在匿名命名空间中定义所有内部符号。当然,这样的约定将是——作为约定通常是——一个品味问题。
你的第二个反驳论点似乎在反对一个不存在的差异。匿名命名空间对隐藏在函数范围内的名称没有影响。
可以说它提高了清晰度。拥有匿名命名空间更清楚 "this code is implementation detail for this compilation unit alone, not intended as part of the unit's interface"。因为无论如何您都必须以这种方式为本地 类 或结构使用匿名名称空间(没有其他方法可以本地化它们),所以以这种方式封装所有本地构造是合理的。
我在公司到处都能看到这样的代码:
namespace {
const MAX_LIMIT = 50;
const std::string TOKEN = "Token";
}
我很困惑为什么你需要一个匿名命名空间。一方面,您需要 MAX_LIMIT
和 TOKEN
的本地翻译单元。但是由于const
,这已经在没有匿名命名空间的情况下实现了。 static const
和简单的const
都实现了本地翻译单元
另一方面,如果您的文件中某处有一个名称相同的变量,则不会发生命名冲突。
int foo()
{
std::string TOKEN = "MyToken"; // Clash! ::TOKEN vs TOKEN can be used.
}
这将证明匿名命名空间的合理性。但是,您多久需要在函数中使用一个实际上已经被在函数外部声明的 const
变量使用的变量名?我的回答是永远不会。所以在实践中,对我来说不需要未命名的命名空间。有什么提示吗?
正如您所解释的,namespace
是多余的。您可以删除 namespace {
并匹配 }
.
一个区别是您可以使用不同的名称 ::TOKEN
和 unnamed_namespace::TOKEN
。但这可能只会增加混乱,最好得到一个编译错误。
不确定 post 的后半部分是关于什么的,局部变量 TOKEN
隐藏了 ::TOKEN
和 unnamed_namespace::TOKEN
。因此,更改对这种情况没有影响。
在这种特殊情况下,命名空间确实是多余的,因为 const 命名空间作用域变量在默认情况下确实具有内部链接。
考虑以后更改代码的可能性。也许其中一个变量毕竟不应该是 const 。但使其成为非常量也会改变默认链接。即使在这样的更改之后,匿名名称空间仍将保持内部链接。换句话说,anon 命名空间分离了对常量性和链接的关注。这是否是一件好事,取决于上下文。
请注意,使用 static
关键字可以实现相同的目的。由于这与 anon 命名空间具有完全相同的效果,因此选择主要是审美,因此基于意见。
使用匿名命名空间而不是 static
的一个论据可能是一致性。您不能使用 static
定义具有内部链接的类型。由于某些内部符号(类型)不能在匿名命名空间之外定义,因此您可以约定在匿名命名空间中定义所有内部符号。当然,这样的约定将是——作为约定通常是——一个品味问题。
你的第二个反驳论点似乎在反对一个不存在的差异。匿名命名空间对隐藏在函数范围内的名称没有影响。
可以说它提高了清晰度。拥有匿名命名空间更清楚 "this code is implementation detail for this compilation unit alone, not intended as part of the unit's interface"。因为无论如何您都必须以这种方式为本地 类 或结构使用匿名名称空间(没有其他方法可以本地化它们),所以以这种方式封装所有本地构造是合理的。