为什么有注入的类名?

ikh*_*ikh 142 c++

最近,我看到了一个奇怪的C++特性:注入类名.

class X { };
X x1;
class X::X x2; // class X::X is equal to X
class X::X::X x3; // ...and so on...
Run Code Online (Sandbox Code Playgroud)

但我无法弄清楚为什么这个功能是必要的.有没有需要此功能的练习?

我听说旧C++中不存在这个功能.然后,什么时候介绍?C++ 03?C++ 11?

Jon*_*ely 159

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

void X() { }
class X {
public:
  static X create() { return X(); }
};
Run Code Online (Sandbox Code Playgroud)

create()函数是创建临时X对象还是调用该函数X?在命名空间范围内,它会调用该函数,因此inject-class-name的目的是确保在X名称正文中始终找到类本身(因为在查看封闭之前,名称查找在类的自己范围内开始范围).

它在类模板中也很有用,其中注入的类名可以在没有模板参数列表的情况下使用,例如使用简单Foo而不是完整的模板ID Foo<blah, blah, blah>,因此很容易引用当前的实例化.有关C++ 98和C++ 03之间的更改,请参阅DR 176.

注入类名的想法出现在C++ 98中,但术语对于C++ 03来说是新的.

C++ 98说:

一个类名被插入在其中后立即宣布的范围类的名字能够被看见.类名也插入到类本身的范围内.

DR 147更改了第二句,所以C++ 03在[class]/2中说:

一个类名被插入在其中后立即宣布的范围类的名字能够被看见.的类名也被插入到类本身的范围; 这被称为注入类名.

即使在C++ 98之前,ARM也有大致相同的措辞,这意味着类的名称总是可以在类体中用来引用类本身:

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

  • 例如,

    class link { link* next; };

  • 我经常被问到,但从来没有建立一个指出问题的简单例子.所以+1为例子. (2认同)