为什么会有一个注入的类名?


147

最近,我看到了一个奇怪的C ++功能:注入的类名

class X { };
X x1;
class X::X x2; // class X::X is equal to X
class X::X::X x3; // ...and so on...

但我不知道为什么需要此功能。有没有实践需要此功能?

我听说旧的C ++中不存在此功能。那么,什么时候引入的呢?C ++ 03?C ++ 11?


好友,您可以在Skype上看吗?我无法联系您
Irinel Iovan

Answers:


162

注入的类名意味着X被声明为的成员X,因此内部的名称查找X始终会找到当前类,而不是X在同一封闭范围内声明的另一个类,例如

void X() { }
class X {
public:
  static X create() { return X(); }
};

create()函数创建一个临时X对象或调用函数X?在名称空间范围内,它将调用该函数,因此,注入的类名的目的是确保在X名称主体内始终能够找到类本身(因为名称查找是在类的自身范围内开始的,然后才查找封闭的内容)范围)。

这在类模板内部也很有用,在这种情况下,可以在没有模板参数列表的情况下使用注入的类名,例如,仅使用Foo而不是完整的template-id Foo<blah, blah, blah>,因此可以轻松地引用当前实例。有关澄清了C ++ 98和C ++ 03之间的更改,请参阅DR 176

在C ++ 98中存在注入类名的想法,但该术语对于C ++ 03是新的。

C ++ 98说:

在看到类名之后,立即将一个类名插入到声明该类名的范围中。类名也插入到类本身的范围内。

第二句由DR 147更改,因此C ++ 03在[class] / 2中说:

在看到类名之后,立即将一个类名插入到声明该类名的范围中。的类名也被插入到类本身的范围; 这就是所谓的Injection-class-name

即使在C ++ 98之前,ARM的措词也大致相同,这意味着可以始终在类主体中使用该类的名称来引用该类本身:

即使在类说明符本身的成员列表中类的名称也可以用作类名称

  • 例如,

    class link { link* next; };


2
我经常被问到这个问题,但是从来没有建立一个简单的例子来指出问题所在。所以+1为例。
dhein

1
如果您运行clang ++ your_program.cpp -Xclang -ast-dump并且看到您的类,然后看到一个注入的类子节点,则可以清楚地看到这一点。
xaxxon
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.