繁体   English   中英

合格基类的名称查找

[英]Name lookup of qualified base class

考虑以下代码:

#include <iostream>

namespace D
{
    struct S { S(){std::cout << "D::S\n";} };
}

struct S { S(){std::cout << "S\n";} };

struct X: D::S
{
    X(): S() {}        // (1)
    // X(): D::S() {}  // (2)

    void f() { S s; }
};

int main() { X x; x.f(); }

来自g ++的输出是:

D::S
D::S

我的问题是:

  • (1)的工作方式-虽然我将基类的名称专门指定为D::S
  • (1)和(2)都需要工作吗?
  • 为什么S s; f()内部引用D::S而不是::S

显然,在类D::S的内部,名称S指向其自身。 这称为“注入的类名”。 您可以认为它好像D::S有一个公共成员typedef,其名称为S

  • (1)的工作方式-虽然我将基类的名称专门指定为D :: S

X源自D::S ,因为您在X的基类列表中是这样说的。

派生类可以访问在基类中声明的名称,因此X名称查找首先查看其自身的成员及其基类的成员,然后在X之外的封闭范围内查找名称。 由于注入的类名SD::S的成员,因此可以在X找到它,这就是(1)起作用的原因。 该类型::S没有找到,因为名称查找发现注入的类名和从不看在封闭范围(如果它没有找到::S的代码将无法编译,因为::S不是一个基类的X ) 。

作为类推,考虑使用D::S声明的成员typedef的示例:

namespace D {
  struct S {
    struct S { S(){std::cout << "D::S\n";} };
    typedef S AnotherName;
  };
}

struct X : D::S {
  X() : AnotherName() { }
};

之所以AnotherName是因为在基类中找到了名称AnotherName ,并且该名称是基类D::S的同义词。 注入的类名的工作方式类似,不同之处在于,注入的类名是该类自己的名称S ,而不是其他名称,例如AnotherName

  • (1)和(2)都需要工作吗?

是。

(2)的作品,因为D::S是完全合格的命名的S所以它指的是同一类型,但使用它的“全名”非成员必须使用引用类型。

  • 为什么S s; 在f()内部引用D :: S而不是:: S?

因为像构造函数一样, f()X的成员,所以名称查找首先在X (及其基类)的范围内进行,然后查找注入的类名称。 它永远不会在全局范围内看到类型::S ,因为它会找到名称S作为基类的成员并停止查找。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM