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

标签 c++ namespaces refactoring 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
};

但我更愿意将人们(实际上)感兴趣的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
    }

    ...
}

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

最佳答案

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 ...(重点是我的)

$7.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; }

关于c++ - 每个编译单元是否只有一个未命名的命名空间?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36890298/

相关文章:

clojure - 在 ClojureScript 中不能要求 goog.fx.Dragger

ruby-on-rails - rails : Facebox link if condition is satisfied

database - 在生产中重构数据库的最佳实践?

c++ - 同一类中类型的前向声明

c++ - 我需要创建一个非常大的位/ bool 值数组。我将如何在 C/C++ 中执行此操作?

c# - 在 Windows 8 Metro-App 中打开 extern SQLite-Database?

namespaces - 无法选择标签名称 - JS

Javascript:为什么全局范围内的变量成为其 'this' 的属性,但它不会发生在新对象的功能范围内的变量上

javascript - 在 redux 函数中重构变量

c++ - 构造函数中的引用初始化问题