【问题标题】:Rationale behind using namespace behavior使用命名空间行为背后的基本原理
【发布时间】:2017-07-04 18:36:52
【问题描述】:

引用标准:

using 指令指定指定命名空间中的名称 可以在 using 指令出现的范围内使用 使用指令。在非限定名称查找 (3.4.1) 期间,名称 看起来好像它们是在最近的封闭命名空间中声明的 其中包含 using 指令和指定的命名空间。

看看这段代码:

namespace A {

    int fn() { return 1; }

}

namespace Inner {

    int fn() { return 2; }

    namespace B {

        using namespace A;

        int z = fn();

    }

}

在这里,在我知道命名空间的确切规则之前,我曾预计z 将被初始化为1,因为我写了using namespace A,因此预计将使用A::fn()。但事实并非如此,z 将被初始化为 2,因为 Inner::fn() 被调用是因为我引用的规则。

这种行为背后的基本原理是什么:“好像它们是在最近的封闭命名空间中声明的,其中包含使用指令和指定命名空间”?

如果using namespace 用作对该命名空间中的所有内容应用 using 声明,会有什么缺点?

注意:this 是促使我提出这个问题的相关问题。

【问题讨论】:

  • 这对我来说似乎也违反直觉,但它似乎从 C++98 开始就是这样。

标签: c++ namespaces language-lawyer


【解决方案1】:

命名空间系统的一个理想属性是我所说的增量 API 兼容性。也就是说,如果我向命名空间添加一个符号,那么任何以前工作的程序都应该继续工作并且意味着同样的事情。

现在,带有重载的普通 C++ 不增量 API 兼容

int foo(long x) { return 1; }

int main()
{
    foo(0);
}

现在我添加了重载int foo(int x) { return 2; },程序默默地改变了含义。

无论如何,当 C++ 人员设计namespace 系统时,他们希望在递增外部 API 时,以前工作的代码不应更改选择符号的名称空间。从您的示例中,以前的工作代码将类似于:

namespace A {
    //no fn here, yet    
}

namespace Inner {

    int fn() { return 2; }

    namespace B {

        using namespace A;
        int z = fn();
    }
}

并且z 很容易初始化为2。现在使用名为 fn 的符号扩充命名空间 A 不会改变该工作代码的含义。

相反的情况并不真正适用:

namespace A {
    int fn() { return 1; }
}

namespace Inner {

    // no fn here

    namespace B {

        using namespace A;
        int z = fn();
    }
}

这里z被初始化为1。当然,如果我将fn 添加到Inner 会改变程序的含义,但Inner 不是外部API:实际上,当Inner 最初编写时,A::fn 确实已经存在(它被召唤了!),所以没有理由不知道冲突。


一个比较实际的例子

想象一下这个 C++98 程序:

#include <iostream>

namespace A {
int move = 0;
void foo()
{
    using namespace std;
    cout << move << endl;
    return 0;
}
}

int main()
{
    A::foo();
    return 0;
}

现在,如果我用 C++11 编译它,由于using 规则,一切正常。如果 using namespace std 用作对该命名空间中的所有内容应用 using 声明,则该程序将尝试打印函数 std::move 而不是 A::move

【讨论】:

    猜你喜欢
    • 2017-02-15
    • 1970-01-01
    • 2017-03-09
    • 2011-03-11
    • 1970-01-01
    • 2015-08-18
    • 1970-01-01
    • 2014-12-19
    • 1970-01-01
    相关资源
    最近更新 更多