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

and*_*ley 8 c++ refactoring namespaces legacy-code

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

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

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

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

    ...
}

class ActuallyInteresting {
    // uses OldUtils
};
Run Code Online (Sandbox Code Playgroud)

但是我希望ActuallyInteresting人们将(实际上)感兴趣的代码靠近文件的顶部,例如从第50行开始,而不是在底部,例如从第1000行开始.将可怕的实用程序类拆分为单独的编译单位不是一个选项,出于更高层次的原因我不会进入!

所以我想知道是否有可能将短类声明 - 没有方法定义 - 放在文件顶部的未命名命名空间中,并在底部的另一个未命名的命名空间中放置更长的方法定义:

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

class ActuallyInteresting {
    // uses OldUtils
};

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

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

    ...
}
Run Code Online (Sandbox Code Playgroud)

这两个"独立"的未命名命名空间是否会被视为编译单元中的相同范围,还是会为每个命名空间生成不同的唯一命名空间?标准有什么可说的吗?

Whi*_*TiM 7

这两个"独立"的未命名命名空间是否会被视为编译单元中的相同范围,还是会为每个命名空间生成不同的唯一命名空间?标准有什么可说的吗?

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

引用最新的标准草案 ......(重点是我的)

$ 7.3.1.1 unnamed-namespace-definition的行为就像被替换为

inlineopt namespace unique { /* empty body */ }
using namespace unique ;
namespace unique { namespace-body }
Run Code Online (Sandbox Code Playgroud)

其中inline出现当且仅当它出现在未命名的名称空间定义和所有出现 unique 在翻译单元由相同的标识符代替,并且该标识符从所有其它标识符的不同之处翻译单元

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

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

int main(){ ++c; }
Run Code Online (Sandbox Code Playgroud)

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

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

int main(){ ++c; }
Run Code Online (Sandbox Code Playgroud)