每个编译单元是否只有一个未命名的命名空间?

Is there only one unnamed namespace per compilation unit?

我继承了一段可怕的遗留代码,其中包括大约 1000 行实用程序 class 定义,这些定义需要出现在源文件中的 "real" 代码之前。为了避免与其他可能也有相关遗留 classes 的模块发生冲突,我已将实用程序 class 放入未命名的命名空间中:

namespace {
    class OldUtils {
        OldUtils();
        int foo();
        double bar();
    };

    OldUtils::OldUtils() {
        // hundreds of lines
    }

    int OldUtils::foo() {
        // hundreds more lines
    }

    ...
}

class ActuallyInteresting {
    // uses OldUtils
};

但我更希望将人们(实际上)感兴趣的 ActuallyInteresting 代码放在文件顶部附近,例如从第 50 行开始,而不是在底部,例如从第 1000 行开始。将可怕的实用程序 class 拆分为单独的编译单元不是一种选择,出于更高级别的原因,我不会深入探讨!

所以我想知道是否可以将简短的 class 声明(没有方法定义)放在文件顶部的未命名名称空间中,而将更长的方法定义放在另一个未命名的名称空间中底部的命名空间:

namespace {
    class OldUtils {
        OldUtils();
        int foo();
        double bar();
    };
}

class ActuallyInteresting {
    // uses OldUtils
};

namespace {
    OldUtils::OldUtils() {
        // hundreds of lines
    }

    int OldUtils::foo() {
        // hundreds more lines
    }

    ...
}

这两个 "separate" 未命名的命名空间是否会被视为编译单元内的相同范围,还是会为每个命名空间生成不同的唯一命名空间?标准对此有何规定?

Will these two "separate" unnamed namespaces be treated as the same scope within the compilation unit, or will different unique namespaces be generated for each? Does the standard have anything to say about this?

是的,它们在编译单元中将被视为相同。而且标准确实有话要说....

引用 latest standard draft...(重点是我的)

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

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

where inline appears if and only if it appears in the unnamed-namespace-definition and all occurrences of unique in a translation unit are replaced by the same identifier, and this identifier differs from all other identifiers in the translation unit

编译这个短程序,你的编译器应该抱怨变量重新声明...

namespace { int c = 0; }
namespace { double c = 8; }

int main(){ ++c; }

但是,要访问未命名命名空间中的变量,您可以使用访问全局变量的常规方式...因此这会起作用。

namespace { int c = 0; }
namespace { void f(){ c = 8; } }

int main(){ ++c; }