Declarations
宣言 は、名前をC++プログラムに導入(または再導入)する方法です。すべての宣言が実際に何かを宣言するわけではなく、各種エンティティはそれぞれ異なる方法で宣言されます。 定義 は、名前で識別されるエンティティを使用するのに十分な宣言です。
宣言は以下のいずれかです:
|
(C++11以降) |
-
空の宣言 (
;) - decl-specifier-seq を持たない関数宣言:
attr
(任意)
declarator
;
|
|||||||||
| attr | - | (since C++11) 任意の数の 属性 のシーケンス |
| declarator | - | 関数宣言子 |
- この宣言はコンストラクタ、デストラクタ、またはユーザー定義型の conversion function を宣言しなければなりません。これは template declaration 、 explicit specialization または明示的インスタンス化の一部としてのみ使用できます。
- block-declaration (ブロック内に現れることができる宣言( ブロック を参照))。これは以下のいずれかになります:
| (C++11以降) |
| (C++20以降) | |
| (C++11以降) |
-
- 単純宣言
内容単純宣言単純宣言とは、1つまたは複数の識別子(通常は変数)を導入、作成、およびオプションで初期化する文です。
1) 初期化子付きの宣言子。
2) 初期化子のない宣言子。
指定子宣言指定子 ( decl-specifier-seq ) は、任意の順序で以下の空白区切りの指定子の列です:
Attributes は decl-specifier-seq 内に現れることがあり、その場合、それらは先行する指定子によって決定される型に適用されます。 宣言指定子シーケンス内での任意の指定子の繰り返し、例えば decl-specifier-seq 内の const static const や virtual inline virtual はエラーとなります 、ただし long が2回出現することは許可されます (C++11以降) 。 宣言子init-declarator-list 内の各 init-declarator は、同じ指定子を持つ独立した宣言であるかのように処理されます: S D1, D2, D3 ; は S D1 ; S D2 ; S D3 ; として扱われます。 各宣言子は、正確に1つのオブジェクト、参照、関数、または(typedef宣言の場合)型エイリアスを導入します。その型は decl-specifier-seq によって提供され、宣言子内の & (参照)や [ ] (配列)や ( ) (関数返却)などの演算子によって任意に修飾されます。これらの演算子は、以下に示すように再帰的に適用できます。 A declarator は以下のいずれかです:
1)
宣言された
name
。
2)
修飾識別子(
qualified identifier
(
qualified-id
))を使用する宣言子は、以前に宣言された
namespace member
または
class member
を定義または再宣言します。
5)
メンバへのポインタ宣言
: 宣言
S C
::
*
D
;
は
D
を
C
のメンバへのポインタとして宣言し、その型は
decl-specifier-seq
S
によって決定される。
nested-name-specifier
は
名前とスコープ解決演算子のシーケンス
::
9)
関数宣言子
.
noptr-declarator
任意の有効な宣言子。ただし、*、&、または&&で始まる場合は括弧で囲む必要があります。
オプションの末尾戻り値型で終了しても構いません。
(C++11以降)
10)
括弧で囲まれた宣言子。
cv は const および volatile 修飾子のシーケンスであり、各修飾子はシーケンス内に最大1回のみ出現することができます。
注記ブロック内で block-declaration が現れた場合、かつ宣言によって導入された識別子が以前に外側のブロックで宣言されていたとき、 外側の宣言は隠蔽されます (そのブロックの残りの部分に対して)。 自動記憶域期間を持つ変数を宣言する場合、その宣言文が実行されるときに初期化されます。ブロック内で宣言されたすべての自動変数は、ブロックから退出する際に(例外、goto、またはブロック終端への到達など、どのようにブロックを退出したかに関係なく)破棄され、初期化の順序と逆の順序で破棄されます。 例注: この例は、複雑な宣言が言語文法の観点からどのように解析されるかを示しています。他の一般的な記憶法としては: スパイラルルール 、 内側から外側への読み方 、および 宣言が使用法を反映する があります。また自動解析ツールが https://cdecl.org で利用可能です。
このコードを実行
#include <type_traits> struct S { int member; // decl-specifier-seq is "int" // declarator is "member" } obj, *pObj(&obj); // decl-specifier-seq is "struct S { int member; }" // declarator "obj" declares an object of type S // declarator "*pObj" declares a pointer to S, // and initializer "(&obj)" initializes it int i = 1, *p = nullptr, f(), (*pf)(double); // decl-specifier-seq is "int" // declarator "i" declares a variable of type int, // and initializer "= 1" initializes it // declarator "*p" declares a variable of type int*, // and initializer "= nullptr" initializes it // declarator "f()" declares (but doesn't define) // a function taking no arguments and returning int // declarator "(*pf)(double)" declares a pointer to function // taking double and returning int int (*(*var1)(double))[3] = nullptr; // decl-specifier-seq is "int" // declarator is "(*(*var1)(double))[3]" // initializer is "= nullptr" // 1. declarator "(*(*var1)(double))[3]" is an array declarator: // Type declared is: "(*(*var1)(double))" array of 3 elements // 2. declarator "(*(*var1)(double))" is a pointer declarator: // Type declared is: "(*var1)(double)" pointer to array of 3 elements // 3. declarator "(*var1)(double)" is a function declarator: // Type declared is: "(*var1)" function taking "(double)", // returning pointer to array of 3 elements. // 4. declarator "(*var1)" is a pointer declarator: // Type declared is: "var1" pointer to function taking "(double)", // returning pointer to array of 3 elements. // 5. declarator "var1" is an identifier. // This declaration declares the object var1 of type "pointer to function // taking double and returning pointer to array of 3 elements of type int" // The initializer "= nullptr" provides the initial value of this pointer. // C++11 alternative syntax: auto (*var2)(double) -> int (*)[3] = nullptr; // decl-specifier-seq is "auto" // declarator is "(*var2)(double) -> int (*)[3]" // initializer is "= nullptr" // 1. declarator "(*var2)(double) -> int (*)[3]" is a function declarator: // Type declared is: "(*var2)" function taking "(double)", returning "int (*)[3]" // ... int main() { static_assert(std::is_same_v<decltype(var1), decltype(var2)>); } 不具合報告以下の動作変更の欠陥報告書は、以前に公開されたC++規格に対して遡及的に適用されました。
関連項目
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||