c++的一个特性是能够创建未命名(匿名)的名称空间,如下所示:

namespace {
    int cannotAccessOutsideThisFile() { ... }
} // namespace

您可能会认为这样的特性毫无用处——因为不能指定名称空间的名称,因此不可能从外部访问其中的任何内容。但是,这些未命名的名称空间可以在创建它们的文件中访问,就像对它们有一个隐式的using子句一样。

我的问题是,为什么或者什么时候这比使用静态函数更可取?或者它们本质上是做同一件事的两种方式?


当前回答

就我个人而言,我更喜欢静态函数而不是无名称的名称空间,原因如下:

It's obvious and clear from function definition alone that it's private to the translation unit where it's compiled. With nameless namespace you might need to scroll and search to see if a function is in a namespace. Functions in namespaces might be treated as extern by some (older) compilers. In VS2017 they are still extern. For this reason even if a function is in nameless namespace you might still want to mark them static. Static functions behave very similar in C or C++, while nameless namespaces are obviously C++ only. nameless namespaces also add extra level in indentation and I don't like that :)

所以,我很高兴看到静态函数不再被弃用了。

其他回答

在第7.3.1.1节第2段中,c++标准如下:

static关键字的用法是 类中声明对象时不支持 命名空间范围,即未命名的命名空间 提供了一个更好的选择。

Static仅适用于对象、函数和匿名联合的名称,不适用于类型声明。

编辑:

反对使用static关键字(影响翻译单元中变量声明的可见性)的决定已被推翻(ref)。在这种情况下,使用静态名称空间或未命名名称空间本质上是做完全相同的事情的两种方式。更多讨论请参见这个SO问题。

未命名的名称空间仍然具有允许您定义翻译单元局部类型的优势。请参阅这个SO问题了解更多细节。

感谢迈克·珀西让我注意到这一点。

我刚才在看你的问题时才了解到这个特点,我只能猜测。这似乎比文件级静态变量提供了几个优势:

匿名名称空间可以嵌套在另一个名称空间中,提供多级保护,使符号无法逃脱。 可以在同一个源文件中放置多个匿名名称空间,从而在同一个文件中创建不同的静态级作用域。

我想知道是否有人在实际代码中使用过匿名名称空间。

c++ 98标准不赞成为此目的使用static关键字。静态的问题在于它不适用于类型定义。它也是一个重载关键字,在不同的上下文中以不同的方式使用,因此未命名的名称空间简化了一些事情。

将方法放在匿名名称空间中可以防止您意外地违反One Definition Rule,允许您不必担心将您的helper方法命名为与您可能链接的其他方法相同的方法。

而且,正如luke所指出的,标准更喜欢匿名名称空间而不是静态成员。

我最近开始在代码中用匿名名称空间替换静态关键字,但很快就遇到了一个问题,即名称空间中的变量在调试器中不再可用。我使用的是VC60,所以我不知道其他调试器是否没有问题。我的解决方法是定义一个“模块”命名空间,在那里我给它我的cpp文件的名字。

例如,在我的xmlutil_cpp文件中,我定义了一个名称空间XmlUtil_I{…}用于我的所有模块变量和函数。这样我就可以在调试器中应用XmlUtil_I::资格来访问变量。在本例中,_I将其与公共名称空间区分开来,例如我可能希望在其他地方使用的XmlUtil。

我认为,与真正的匿名方法相比,这种方法的潜在缺点是,有人可能会在其他模块中使用名称空间限定符,从而违反所需的静态作用域。我不知道这是否是一个主要的问题。