最近、奇妙な 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
注入されたクラス名は が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>
と、現在のインスタンス化を簡単に参照できます。DR176C++98 と C++03 の間の変更により、そのことが明確になりました。
注入されたクラス名の概念は C++98 に存在していましたが、その用語は C++03 では新しいものでした。
C++98 では次のように述べられています:
あクラス名宣言されたスコープに挿入され、クラス名が表示されます。クラス名もクラス自体のスコープに挿入されます。
2番目の文は、DR147C++03 では [class]/2 で次のように記述されています:
あクラス名宣言されたスコープに挿入され、クラス名が見られます。クラス名クラス自体のスコープにも挿入されます。これは注入クラス名。
C++98 以前でも、ARM にはほぼ同等の文言があり、クラス名をクラス本体で常に使用してクラス自体を参照できます。
クラス名は、クラス名たとえメンバーリストクラス指定子自体の。
- 例えば、
class link { link* next; };