嵌套未命名命名空间?

37

当使用未命名的命名空间时,如果它嵌套在另一个命名空间中,是否存在任何问题?例如,在以下代码中,Foo1.cpp和Foo2.cpp之间是否有任何实际区别:

// Foo.h
namespace Foo
{
    void fooFunc();
}

// Foo1.cpp
namespace Foo
{
    namespace
    {
        void privateFunction()
        {
            ...
        }
    }

    void fooFunc()
    {
        privateFunction();
    }
}

// Foo2.cpp
namespace
{
    void privateFunction()
    {
        ...
    }
}

namespace Foo
{
    void fooFunc()
    {
        privateFunction();
    }
}

导出的符号将会不同。请查看nm输出。 - Nikolai Fetissov
5
技术术语是“未命名命名空间”,而不是匿名的。 - GManNickG
1
联合体是匿名的,命名空间是无名的。但是谁在乎呢 :) - Kirill V. Lyadvinsky
4
尽管这个术语没有名称,但如果您使用工具 nmgdb 进行检查,它们会将其称为 anonymous namespace,因此产生混淆是可以理解的。 - David Rodríguez - dribeas
2个回答

33

未命名命名空间可以被视为一个普通的命名空间,其具有唯一的名称,但你不知道它的名称。根据C++标准7.3.1.1:

未命名命名空间定义的行为就像被以下代码替换一样:

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

在翻译单元中,所有唯一项的出现都被替换为相同的标识符,并且此标识符与整个程序中的所有其他标识符都不同。

没有其他问题。


4

对你的目的来说可能没有真正的区别。它影响到 privateFunction 在你的 cpp 文件中可见的位置。如果在两个文件的末尾添加 void barFunc() { privateFunction(); },那么 Foo2.cpp 就会编译通过,而 Foo1.cpp 不会。

通常情况下,你不会在同一个 cpp 文件中定义来自许多不同命名空间的外部符号,因此这种差异不会出现。


“两个文件的结尾”指的是“在namespace Foo {}之后”? - Mike C
1
@MikeC - 是的,我认为@SteveJessop的意思是在namespace Foo {}之后。 - Pietro

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