为什么有注入的类名?

时间:2014-08-28 13:10:48

标签: 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...

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

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

1 个答案:

答案 0 :(得分:153)

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

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

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说:

  

class-name 被插入到在看到 class-name 之后立即声明它的范围内。类名也会插入到类本身的范围内。

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

  

class-name 被插入到在看到 class-name 之后立即声明它的范围内。 class-name 也会插入到类本身的范围内;这被称为 inject-class-name

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

  

即使在类说明符本身的 member-list 中,类的名称也可用作类名

     
    
        
  • 例如,          
          

    class link { link* next; };

        
  •