Elaborated type specifier (詳細型指定子)
完全型指定子は、以前に宣言されたクラス名(クラス、構造体、または共用体)や以前に宣言されたenum名を、その名前が非型宣言によって隠されていた場合でも参照するために使用できます。また、新しいクラス名を宣言するためにも使用できます。
目次 |
[編集] 構文
| class-key class-name | (1) | ||||||||
enum enum-name |
(2) | ||||||||
class-key attr (オプション) identifier ; |
(3) | ||||||||
| class-key | - | class、struct、union のいずれか |
| class-name | - | 以前に宣言されたクラス型の名前(オプションで修飾されている)、または以前に型名として宣言されていない識別子 |
| enum-name | - | 以前に宣言された列挙型の名前(オプションで修飾されている) |
| attr | - | (C++11以降) 任意の数の属性 |
不完全列挙宣言は形式(3)に似ていますが、不完全列挙宣言後、列挙型は完全型になります。
[編集] 解説
形式(3)は完全型指定子の特殊なケースで、通常、クラスの前方宣言と呼ばれます。形式(3)の説明については、前方宣言を参照してください。以下は、形式(1)および(2)にのみ適用されます。
完全型指定子内のclass-nameまたはenum-nameは、単純な識別子または修飾IDのいずれかです。名前は、その出現に応じて非修飾名検索または修飾名検索を使用して検索されます。ただし、いずれの場合も、非型名は考慮されません。
class T { public: class U; private: int U; }; int main() { int T; T t; // error: the local variable T is found class T t; // OK: finds ::T, the local variable T is ignored T::U* u; // error: lookup of T::U finds the private data member class T::U* u; // OK: the data member is ignored }
名前検索が以前に宣言された型名を見つけず、完全型指定子がclass、struct、またはunion(つまり、enumではない)によって導入され、class-nameが非修飾識別子である場合、完全型指定子はそのクラス名のクラス宣言であり、ターゲットスコープは最も近い囲む名前空間またはブロックスコープです。
template<typename T> struct Node { struct Node* Next; // OK: lookup of Node finds the injected-class-name struct Data* Data; // OK: declares type Data at global scope // and also declares the data member Data friend class ::List; // error: cannot introduce a qualified name enum Kind* kind; // error: cannot introduce an enum }; Data* p; // OK: struct Data has been declared
名前がtypedef名、型エイリアス、テンプレート型パラメーター、またはエイリアステンプレート特殊化を参照する場合、プログラムは不正な形式です。それ以外の場合、完全型指定子は、単純型指定子がその型名を導入するのと同じ方法で、宣言に名前を導入します。
template<typename T> class Node { friend class T; // error: type parameter cannot appear in an elaborated type specifier; // note that similar declaration `friend T;` is OK. }; class A {}; enum b { f, t }; int main() { class A a; // OK: equivalent to 'A a;' enum b flag; // OK: equivalent to 'b flag;' }
完全型指定子に存在するclass-keyまたはenumキーワードは、完全型指定子内の名前が参照する宣言の種類と一致する必要があります。
enumキーワードは列挙型(スコープ付きまたはスコープなし)を参照するために使用する必要があります。unionclass-keyは共用体を参照するために使用する必要があります。classまたはstructclass-keyのいずれかは、共用体ではないクラス型を参照するために使用する必要があります(ここではclassとstructキーワードは交換可能です)。
enum class E { a, b }; enum E x = E::a; // OK enum class E y = E::b; // error: 'enum class' cannot introduce an elaborated type specifier struct A {}; class A a; // OK
テンプレート引数として使用される場合、class Tは、完全型指定子によって導入される型Tを持つ名前なしの非型パラメーターではなく、Tという名前の型テンプレートパラメーターです。
[編集] キーワード
[編集] 参照
- C++23標準 (ISO/IEC 14882:2024)
- 6.5.6 完全型指定子 [basic.lookup.elab]
- 9.2.9.4 完全型指定子 [dcl.type.elab]
- C++20 standard (ISO/IEC 14882:2020)
- 6.5.4 完全型指定子 [basic.lookup.elab]
- 9.2.8.3 完全型指定子 [dcl.type.elab]
- C++17 standard (ISO/IEC 14882:2017)
- 6.4.4 完全型指定子 [basic.lookup.elab]
- 10.1.7.3 完全型指定子 [dcl.type.elab]
- C++14 standard (ISO/IEC 14882:2014)
- 3.4.4 完全型指定子 [basic.lookup.elab]
- 7.1.6.3 完全型指定子 [dcl.type.elab]
- C++11 standard (ISO/IEC 14882:2011)
- 3.4.4 完全型指定子 [basic.lookup.elab]
- 7.1.6.3 完全型指定子 [dcl.type.elab]
- C++98 標準 (ISO/IEC 14882:1998)
- 3.4.4 完全型指定子 [basic.lookup.elab]
- 7.1.5.3 完全型指定子 [dcl.type.elab]
| このセクションは未完成です 理由: おそらく9.1[class.name]/2-3のほとんどをcpp/language/classから移動 |