名前空間
変種
操作

Elaborated type specifier (詳細型指定子)

From cppreference.com
< cpp‎ | language
 
 
C++言語
全般
フロー制御
条件実行文
if
繰り返し文 (ループ)
for
範囲for (C++11)
ジャンプ文
関数
関数宣言
ラムダ式
inline指定子
動的例外仕様 (C++17まで*)
noexcept指定子 (C++11)
例外
名前空間
指定子
const/volatile
decltype (C++11)
auto (C++11)
constexpr (C++11)
consteval (C++20)
constinit (C++20)
記憶域期間指定子
初期化
代替表現
リテラル
ブーリアン - 整数 - 浮動小数点数
文字 - 文字列 - nullptr (C++11)
ユーザー定義 (C++11)
ユーティリティ
属性 (C++11)
typedef宣言
型エイリアス宣言 (C++11)
キャスト
メモリ確保
クラス
クラス固有の関数プロパティ
explicit (C++11)
static

特殊メンバ関数
テンプレート
その他
 
 

完全型指定子は、以前に宣言されたクラス名(クラス、構造体、または共用体)や以前に宣言されたenum名を、その名前が非型宣言によって隠されていた場合でも参照するために使用できます。また、新しいクラス名を宣言するためにも使用できます。

目次

[編集] 構文

class-key class-name (1)
enum enum-name (2)
class-key attr (オプション) identifier ; (3)
class-key - classstructunion のいずれか
class-name - 以前に宣言されたクラス型の名前(オプションで修飾されている)、または以前に型名として宣言されていない識別子
enum-name - 以前に宣言された列挙型の名前(オプションで修飾されている)
attr - (C++11以降) 任意の数の属性
1) クラス型のための完全型指定子。
2) 列挙型のための完全型指定子。
3) 完全型指定子のみからなる宣言は、常に宣言を含むスコープ内でidentifierという名前のクラス型を宣言します。

不完全列挙宣言は形式(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
}

名前検索が以前に宣言された型名を見つけず、完全型指定子がclassstruct、または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キーワードは列挙型(スコープ付きまたはスコープなし)を参照するために使用する必要があります。
  • union class-key共用体を参照するために使用する必要があります。
  • classまたはstruct class-keyのいずれかは、共用体ではないクラス型を参照するために使用する必要があります(ここではclassstructキーワードは交換可能です)。
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という名前の型テンプレートパラメーターです。

[編集] キーワード

classstructunionenum

[編集] 参照

  • 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]
English 日本語 中文(简体) 中文(繁體)