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

时间:2016-04-27 12:47:48

标签: c++ namespaces refactoring legacy-code

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

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行开始。将可怕的实用程序类拆分成一个单独的编译单元不是一个选项,出于更高层次的原因我不会进入!

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

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

class ActuallyInteresting {
    // uses OldUtils
};

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

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

    ...
}

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

2 个答案:

答案 0 :(得分:6)

  

这两个"分开"未命名的命名空间被视为相同   编译单元内的作用域,或者是不同的唯一名称空间   为每个人生成?标准有什么可说的吗?   此?

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

引用latest standard draft ...(强调是我的)

  

$7.3.1.1 未命名的命名空间定义的行为就像被

替换一样
inlineopt namespace unique { /* empty body */ }
using namespace unique ;
namespace unique { namespace-body }
     

当且仅当inline出现在unique中时才出现   unnamed-namespace-definition和所有出现的 namespace { int c = 0; } namespace { double c = 8; } int main(){ ++c; }   翻译单元替换为相同的标识符,并且这个   标识符与翻译单元中的所有其他标识符不同

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

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

int main(){ ++c; }

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

<String[]>

答案 1 :(得分:-2)

您可以通过检查以下代码是否编译来自行找出答案:

namespace {
   int a;
}

namespace {
   int *b=&a;
}

如果每个命名空间都是唯一的,您希望得到编译错误;在两种情况下,如果未命名的命名空间是相同的命名空间,这将编译没有问题。