【问题标题】:Why is there an injected class name?为什么会有注入的类名?
【发布时间】:2014-10-22 08:47:13
【问题描述】:

最近看到一个奇怪的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?

【问题讨论】:

    标签: c++


    【解决方案1】:

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

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

    create() 函数是创建一个临时的X 对象还是调用函数X?在命名空间范围内它会调用该函数,因此注入类名的目的是确保在 X 的主体内,名称始终可以找到类本身(因为名称查找在查找之前在类自己的范围内开始)在封闭范围内)。

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

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

    C++98 说:

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

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

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

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

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

    • 例如,

      class link { link* next; };

    【讨论】:

    • 我经常被问到这个问题,但从来没有建立一个简单的例子来指出问题。以 +1 为例。
    • 如果你运行 clang++ your_program.cpp -Xclang -ast-dump 并且你看到你的类,然后是注入的类子节点,这可以清楚地看到。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-12-19
    • 2011-02-19
    • 1970-01-01
    相关资源
    最近更新 更多