C ++:使用声明和指令的顺序会影响选择吗?

时间:2019-03-14 17:10:20

标签: c++ using

下面是示例代码

#include <iostream>
using namespace std;


namespace A {
    void f() { cout << "a" << endl; }
}
namespace B {
    void f() { cout << "b" << endl; }
}
namespace C {
    using namespace A;
    using namespace B;
    using A::f;
}
namespace D {
    using A::f;
    using namespace A;
    using namespace B;
}
int main()
{
    C::f();
    D::f();
}

当我在Visual Studio 2015中尝试时,这会打印两次“ a”,此行为是由标准定义的还是此实现特定的?

2 个答案:

答案 0 :(得分:4)

cppreference.com中的以下两段应解释该行为:

  

使用指令[using namespace A;]不会在显示区域中添加任何名称(与使用声明[using A::f;]不同),因此不会阻止使用相同的名称宣布。

     

使用指令是可传递的,用于无条件查找:如果范围包含指定名称空间名称的使用指令,而名称空间本身包含某些名称空间2的using指令,则效果就好像第二个名称空间中的using指令出现在第一个名称空间中。这些可传递名称空间的出现顺序不会影响名称查找。

简单地说:using A::f;就像您在此命名空间中声明该函数一样。 using namespace A;只会导致类型名称查找的行为就像您的情况下的当前名称空间(CD)是A中的名称空间一样。

这类似于

namespace A {
    void f() { cout << "a" << endl; }

    namespace B {
        void f() { cout << "b" << endl; }
    }
}

namespace A {
    namespace B {
        void f() { cout << "b" << endl; }
    }

    void f() { cout << "a" << endl; }
}

等效。

答案 1 :(得分:4)

它是由标准定义的(诸如此类的东西总是如此)。要意识到的关键是,您的各个using namespace行对您的程序没有任何影响。

using namespace Foo是一个“使用指令”,它会影响范围内的代码执行的名称查找。也就是说,如果您的namespace C {}块中的某个更高版本的函数试图找到名为foo的对象,则AB将会是编译器将搜索的位置。 foo。相反,如果以后的代码引用C::foo,则不会改变编译器的外观。单个块中两个连续using namespace的顺序无关紧要,因为每个直到块末尾都具有完全的作用。

您能够在fC中找到D的原因是“使用声明” using A::f。与使用指令不同,使用声明具有将名称注入范围的作用,以便其他代码可以将该名称引用在该范围内。