【问题标题】:What happens when Injected-Class-Name occurs? (C++)当 Injected-Class-Name 发生时会发生什么? (C++)
【发布时间】:2020-01-28 20:00:18
【问题描述】:

根据https://en.cppreference.com/w/cpp/language/injected-class-name

在类范围内,当前类的名称被视为 是公开的成员姓名;这称为注入类名。这 名称的声明点紧随开幕式 类定义的大括号。

int X;
struct X {
    void f() {
        X* p; // OK. X refers to the injected-class-name
        ::X* q; // Error: name lookup finds a variable name, which hides the struct name
    }
};

那么代码中到底发生了什么? X* p变成X::X* p了吗?

【问题讨论】:

    标签: c++ class scope name-lookup injected-class-name


    【解决方案1】:

    那么代码中到底发生了什么? X* p 变成X::X* p 了吗?

    基本上。名称查找规则从最窄的范围开始。当您在f 中执行X* p; 时,会在f 的范围内查找,但什么也找不到。然后它检查X 的范围,因为f 的范围为X。它找到了X,因为它被注入到类作用域中,所以它停在那里,你得到了类类型。

    当您执行::X* q; 时,::X 说在全局命名空间中查找 X,并找到一个变量,而不是类型,因此您会收到错误。

    【讨论】:

    • 所以会出现X::X::foo 之类的事情(例如:stackoverflow.com/questions/46805449/…)是因为 Injected-Class-Name 忽略了这些范围查找,而只是执行 X::foo?
    • @csguy 它本身并没有忽略它,只是X:: 在这种情况下包含XfX 因为它是通过编译器注入的,f 因为你定义了它。如果您执行X::X,那么您将回到您开始的位置,并再次将Xf 作为有效名称。有意义吗?
    • 哦,我明白了。 X 被注入是因为它没有被声明为某个成员名,因为它只是类名?
    • 是的。如果名称未注入,则 class_name::class_name 将无效(构造函数不可访问)
    • @csguy 是的。 C++ 不好玩吗? ;)
    【解决方案2】:

    在全局命名空间中搜索此限定名称 ::X。由于没有具有这样名称的类型(变量声明隐藏了类型struct X),因此编译器会发出错误。

    您可以使用详细的名称,例如

    int X;
    struct X {
        void f() {
            X* p; // OK. X refers to the injected-class-name
            struct ::X* q; // OK. elaborated name struct ::X
        }
    };
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-04-24
      • 1970-01-01
      • 1970-01-01
      • 2010-09-26
      • 2015-09-14
      • 2011-02-23
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多