首页 > 解决方案 > using 指令如何以及在何处注入成员名称?

问题描述

AFAIK using 指令在最近的封闭命名空间中公开或注入命名空间的所有名称。这是来自 C++ 入门:

相反, using 指令使命名空间的全部内容都可用 通常,命名空间可能包含不能出现在本地范围内的定义。因此,using 指令被视为出现在最近的封闭命名空间范围内。

在最简单的情况下,假设我们有一个命名空间 A 和一个函数 f,它们都定义在全局范围内。如果 f 对 A 有 using 指令,那么在 f 中,就好像 A 中的名称出现在 f 的定义之前的全局范围内

并来自 cppreference:

  1. using-directive:从 using-directive 之后的任何名称的非限定名称查找的角度来看,直到它出现的范围结束,来自 ns_name 的每个名称都是可见的,就好像它是在最近的封闭命名空间中声明的一样包含 using-directive 和 ns_name。
#include <iostream>

int x = 1;
int y = 2;
int z = 3;

namespace A{
    namespace B{
        int x = 5;
        int y = 10;
        int z = 0;
    }
    void foo(){
        using namespace A::B;
        std::cout << x << '\t' << y << '\t' << z << '\n'; // x, y, z are not ambiguous
    }
}

namespace AA{
    namespace BB{
        void bar(){
            using namespace A::B;
            std::cout << x << '\t' << y << '\t' << z << '\n'; // x, y, z are ambiguous
        }
    }
}


int main(){

    A::foo(); // works fine
    AA::BB::bar(); // fails to compile

    std::cout << "\ndone!\n";
}

标签: c++namespaces

解决方案


是的,这很令人费解,但你给出的报价准确地解释了发生了什么。在您的第一个示例中(将变量数量减少到 1):

int x = 1;

namespace A {
    namespace B {
        int x = 5;
    }
    void foo(){
        using namespace A::B;
        std::cout << x << '\n';
    }
}

最近的命名空间是A. 本质上,代码相当于

int x = 1;

namespace A {
    int x = 5;

    void foo(){
        std::cout << x << '\n'; // x from NS a.
    }
}

x将是在 A 中定义的名称并将被使用。

在第二个例子中,

namespace AA {
    namespace BB {
        void bar() {
            using namespace A::B;
            std::cout << x << '\n'; 
        }
    }
}

最近的命名空间将是全局命名空间。本质上,代码相当于

int x = 1;
int x = 5;

namespace AA {
    namespace BB {
        void bar() {
            std::cout << x << '\n'; 
        }
    }
}

此代码格式错误,因为x无法在同一范围内重新定义。


推荐阅读