不必要地使用未命名的命名空间C ++

时间:2016-05-12 09:15:48

标签: c++ namespaces anonymous unnamed-namespace

我一直在公司里看到这样的代码:

namespace {

const MAX_LIMIT = 50;
const std::string TOKEN = "Token";

}

我很困惑,为什么你需要一个匿名命名空间。一方面,您需要MAX_LIMITTOKEN的本地翻译单元。但是由于const,没有匿名命名空间就已经实现了这一点。 static const和简单const都实现了本地翻译单元。

另一方面,如果文件中某处有一个名为相同的变量,则没有命名冲突。

int foo()
{
std::string TOKEN = "MyToken"; // Clash! ::TOKEN vs TOKEN can be used.
}

这证明了匿名命名空间的合理性。但是,您在函数中需要一个变量名称的频率实际上是在函数外部声明的const变量吗?我的回答永远不会。所以在实践中,对我来说不需要未命名的命名空间。任何提示?

3 个答案:

答案 0 :(得分:5)

你解释时,namespace是多余的。您可以删除namespace {并匹配}

一个区别是,您可以使用不同的名称::TOKENunnamed_namespace::TOKEN。但这可能只会增加混淆,最好是编译错误。

不确定帖子的后半部分是什么,局部变量TOKEN会影响::TOKENunnamed_namespace::TOKEN。所以这种改变对那种情况没有任何影响。

答案 1 :(得分:3)

在这种特殊情况下,命名空间确实是多余的,因为const命名空间范围变量在默认情况下确实具有内部链接。

考虑以后更改代码的可能性。也许其中一个变量毕竟不应该是const。但是使它成为非const也会改变默认链接。即使在这样的更改之后,匿名命名空间也会保持内部链接。换句话说,匿名命名空间分离了对constness和链接的关注。这是否是一件好事,取决于具体情况。

请注意,使用static关键字可以实现同样的效果。由于这与anon名称空间具有完全相同的效果,因此选择主要是美学的,因此基于意见。

使用匿名命名空间而不是static的参数可以是一致性。您无法使用static定义具有内部链接的类型。由于某些内部符号(类型)无法在匿名命名空间之外定义,因此您可以使用约定来定义匿名命名空间中的所有内部符号。当然,这样的惯例 - 通常是惯例 - 是品味的问题。

你的第二个反驳论点似乎是在反对不存在的差异。匿名命名空间对名称隐藏在函数范围内没有区别。

答案 2 :(得分:0)

可以说它提高了清晰度。拥有一个匿名命名空间说得更清楚“这个代码只是这个编译单元的实现细节,而不是作为单元界面的一部分”。因为无论如何都必须以这种方式为本地类或结构使用匿名命名空间(没有其他方法来本地化它们),以这种方式封装所有本地构造是合理的。