Elaborated type specifier
詳細型指定子は、以前に宣言されたクラス名(class、struct、union)または列挙型名を参照するために使用できます。たとえその名前が 非型宣言によって隠蔽されていた場合でも 使用可能です。また、新しいクラス名を宣言するためにも使用できます。
目次 |
構文
| class-key class-name | (1) | ||||||||
enum
enum-name
|
(2) | ||||||||
class-key
attr
(optional)
identifier
;
|
(3) | ||||||||
| class-key | - | class , struct , union のいずれか |
| class-name | - | 事前に宣言されたクラス型の名前( 修飾 されている場合もある)、または型名として事前に宣言されていない識別子 |
| enum-name | - | 事前に宣言された列挙型の名前( 修飾 されている場合もある) |
| attr | - | (C++11以降) 任意の数の 属性 |
不透明enum宣言 は形式 (3) に似ていますが、不透明enum宣言の後ではenum型は完全型となります。
説明
形式 (3) は elaborated type specifier の特殊なケースであり、通常クラスの 前方宣言 として参照されます。形式 (3) の詳細については、 Forward declaration を参照してください。以下は形式 (1) および (2) にのみ適用されます。
詳細型指定子における class-name または enum-name は、単純な識別子か qualified-id のいずれかです。名前はその出現形式に応じて、 unqualified name lookup または qualified name lookup を使用して検索されます。ただし、いずれの場合も非型名は考慮されません。
class T { public: class U; private: int U; }; int main() { int T; // エラー: ローカル変数Tが見つかる class T t; // OK: ::Tが見つかり、ローカル変数Tは無視される T::U* u; // エラー: T::Uの検索でprivateデータメンバが見つかる class T::U* u; // OK: データメンバは無視される }
名前探索が以前に宣言された型名を見つけられない場合、詳細型指定子が
class
、
struct
、または
union
(つまり
enum
ではない)によって導入され、かつ
class-name
が修飾されていない識別子である場合、その詳細型指定子は class-name のクラス宣言となり、対象スコープは最も内側の外側の名前空間またはブロックスコープとなります。
template<typename T> struct Node { struct Node* Next; // OK: Nodeのルックアップは注入されたクラス名を見つける struct Data* Data; // OK: グローバルスコープで型Dataを宣言 // 同時にデータメンバDataも宣言 friend class ::List; // エラー: 修飾名を導入できない enum Kind* kind; // エラー: enumを導入できない }; Data* p; // OK: struct Dataは宣言済み
名前が typedef名 、 型エイリアス 、 テンプレート型パラメータ 、または エイリアステンプレートの特殊化 を参照する場合、プログラムは不適格となる。それ以外の場合、詳細型指定子は 単純型指定子 がその型名を導入するのと同様の方法で、宣言に名前を導入する。
template<typename T> class Node { friend class T; // エラー: 型パラメータは詳細型指定子に現れることはできません; // 注記: 類似の宣言 `friend T;` は有効です。 }; class A {}; enum b { f, t }; int main() { class A a; // 有効: 'A a;' と同等 enum b flag; // 有効: '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; // エラー: 'enum class' は詳細型指定子を導入できません struct A {}; class A a; // OK
テンプレート引数として使用される場合、
template argument
、
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規格 (ISO/IEC 14882:2020):
-
- 6.5.4 詳細型指定子 [basic.lookup.elab]
-
- 9.2.8.3 詳細型指定子 [dcl.type.elab]
- C++17標準 (ISO/IEC 14882:2017):
-
- 6.4.4 詳細型指定子 [basic.lookup.elab]
-
- 10.1.7.3 詳細型指定子 [dcl.type.elab]
- C++14標準 (ISO/IEC 14882:2014):
-
- 3.4.4 詳細型指定子 [basic.lookup.elab]
-
- 7.1.6.3 詳細型指定子 [dcl.type.elab]
- C++11標準 (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から抽出する必要があります |