【问题标题】:How and where using directive injects member names?using 指令如何以及在何处注入成员名称?
【发布时间】:2021-03-29 21:55:44
【问题描述】:

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";
}
  • 为什么第一个版本可以正常工作(函数A::foo())而第二个版本(AA::BB::bar())不行?

  • 我觉得“将名称注入到 using 指令和命名空间定义的最近命名空间”有点令人困惑。

【问题讨论】:

    标签: c++ namespaces


    【解决方案1】:

    是的,这很令人费解,但是您给出的报价准确地解释了正在发生的事情。在您的第一个示例中(将变量数减少到 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

    【讨论】:

      猜你喜欢
      • 2022-08-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-04-01
      • 2020-11-01
      • 2017-06-03
      • 2014-05-28
      • 1970-01-01
      相关资源
      最近更新 更多