注入されたクラス名があるのはなぜですか?


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?


バディ、スカイプで見れる?連絡が取れません
Irinel Iovan

回答:


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さんのコメント:

クラス名は、直後に宣言された範囲内に挿入されたクラス名が見られています。クラス名もクラス自体のスコープに挿入されます。

2番目の文はDR 147によって変更されたため、C ++ 03は[クラス] / 2で次のように述べています。

クラス名は、直後に宣言された範囲内に挿入されたクラス名が見られています。クラス名は、クラス自体の範囲に挿入されます。これは、注入されたクラス名として知られています。

C ++ 98より前でも、ARMにはほぼ同等の表現があり、クラスの名前をクラス本体で常に使用してクラス自体を参照できることを意味します。

クラスの名前は、クラス指定子自体のメンバーリスト内でもクラス名として使用できます。

  • 例えば、

    class link { link* next; };


2
私はそれをかなり頻繁に尋ねられましたが、問題を指摘する簡単な例を構築することはできませんでした。例では+1。
dhein 2014

1
これは、clang ++ your_program.cpp -Xclang -ast-dumpを実行し、クラスが表示され、次に注入されたクラスの子ノードが表示される場合にはっきりと確認できます。
xaxxon
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.