C++ 命名空间...匿名命名空间是否合法?

5

命名空间 { int Foo(int a); }

像这样。 这段代码合法吗?

这合法吗? 我可以在任何地方引用Foo吗? 还是只能在特定域中使用?

谢谢。


可能是重复的问题:未命名命名空间优于静态变量? - Nawaz
这是合法的,但意思与常规命名空间不同。 :) - jalf
3个回答

9

这是合法的,您可以在同一个翻译单元中任何地方使用Foo

匿名命名空间是指定在变量上使用static,以限制它们的作用域为同一翻译单元的标准方式。

C++03标准第7.3.1.1节未命名命名空间

第2段:

在声明命名空间范围内的对象时,使用static关键字已被弃用,而未命名的命名空间提供了更好的替代方法。


更新:
正如@Matthieu M.在评论中正确指出并且他的回答所述,C++11标准删除了上述引用,这意味着在命名空间范围内声明对象时,static关键字并未被弃用。但是未命名的命名空间仍然是有效的。


@BjörnPollex:啊,是我第二次编辑让我们的答案一样了,哈哈。 - Alok Save
现在我们都添加了标准引号 :) - Björn Pollex
2
@Als:你的回答已经过时了。在C++11中,委员会撤回了对static关键字的使用不再被描述为过时的规定 :) - Matthieu M.
@MatthieuM.:这意味着即使未命名命名空间不再被弃用,我们仍应将其优先于static - Björn Pollex
@BjörnPollex:我认为这意味着我们可以自由地按照自己的方式去做。我必须承认,当我只有一个函数或常量要声明时,我倾向于使用“static”,因为它跟定义紧密相连,所以在未命名的命名空间中,它不是立即清晰的。然而,每当我有类定义时,我都会使用未命名的命名空间,在这种情况下,我将所有的东西都打包在里面... ... 叫我善变 :D - Matthieu M.
显示剩余6条评论

5

这是合法的。您可以在翻译单元内的任何地方引用Foo

根据C++03标准,第7.3.1.1节:

An unnamed-namespace-definition behaves as if it were replaced by

namespace unique { /* empty body */ } using namespace unique;
namespace unique { namespace-body } 

where all occurrences of unique in a translation unit are replaced by the same identifier and this identifier differs from all other identifiers in the entire program.

The use of the static keyword is deprecated when declaring objects in a namespace scope; the unnamed-namespace provides a superior alternative.


未命名的命名空间定义的行为就像被替换一样...。我在这里持不同意见。在未命名的命名空间中,您可以声明/定义变量。但是,在普通的命名空间中,您不能这样做(因为它会导致多个符号链接器错误)。因此,两者的效果并不相同。 - iammilind
3
自从 unique(这是该命名空间的名称)对于所有的翻译单元都不相同,所以你永远不会有重复定义的符号。此外,这是标准中的一句引文,如果你有异议,请向委员会提出。 - Björn Pollex
好的,我原以为 unique 只是一个名称。我不知道标准委员会会给出这样令人困惑的例子 :))。也许 namespace <unique name> { ... } using namespace <unique name>; 会是更合适的措辞。 - iammilind
@iammilind:标准使用不同的字体来表示“unique”并不是代码的一部分;我猜他们也假定人们会读完整个句子。 - Mike Seymour
@MikeSeymour,没错,我同意。对这个答案点赞。谢谢。 - iammilind

3

C++11标准中,该定义略有变化:

7.3.1.1 匿名命名空间 [namespace.unnamed]

1/ 匿名命名空间定义的行为就像被以下内容所替换:

inlineoptnamespace unique { /* empty body */ }
using namespace unique ;
namespace unique { namespace-body }

当 inline 函数或变量出现在未命名命名空间定义中时,所有翻译单元内的 unique 函数或变量都将被替换为相同的标识符,并且该标识符与整个程序中的所有其他标识符均不同。94 [ 例如:

namespace { int i; } // unique ::i
void f() { i++; } // unique ::i++

namespace A {
  namespace {
    int i; // A:: unique ::i
    int j; // A:: unique ::j
  }
  void g() { i++; } // A:: unique ::i++
}

using namespace A;

void h() {
  i++; // error: unique ::i or A:: unique ::i
  A::i++; // A:: unique ::i
  j++; // A:: unique ::j
}

—end example ]


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接