式
式 (expression) とは、演算子 (operator) とその オペランド (operand) のシーケンスであり、ある計算を規定します。
式の評価は、結果を生成する場合があり (例: 2 + 2 の評価は結果として 4 を生成します)、また副作用を生成する場合もあります (例: std::printf("%d", 4) の評価は標準出力に文字 '4' を出力します)。
C++の各々の式は、2つの独立したプロパティ、型 (type) と値カテゴリ (value category) によって特徴付けられます。
目次 |
[編集] 概要
- 値カテゴリ (lvalue, rvalue, glvalue, prvalue, xvalue(C++11以降)) は、式をその値によって分類します。
- 評価順序は、引数と部分式について、中間結果が得られる順序を規定します。
[編集] 演算子
| 一般的な演算子 | ||||||
|---|---|---|---|---|---|---|
| 代入 | インクリメント デクリメント |
算術 | 論理 | 比較 | メンバ アクセス |
その他 |
|
a = b |
++a |
+a |
!a |
a == b |
a[...] |
関数呼び出し a(...) |
| コンマ a, b | ||||||
| conditional a ? b : c | ||||||
| 特殊な演算子 | ||||||
|
static_cast はある型を別の関連する型に変換します | ||||||
- 演算子の優先順位 は、演算子がその引数に結合される順序を定義します
- 代替表現は、一部の演算子の代替の綴りです
- 演算子のオーバーロードは、ユーザー定義クラスで演算子の振る舞いを指定することを可能にします。
[編集] 変換
- 標準変換 ある型から別の型への暗黙的な変換
-
const_cast変換 -
static_cast変換 -
dynamic_cast変換 -
reinterpret_cast変換 - 明示的なキャスト Cスタイルキャスト記法および関数スタイル記法を使用した変換
- ユーザー定義変換 ユーザー定義クラスからの変換を指定することを可能にします
[編集] メモリ確保
[編集] その他
[編集] 一次式
任意の演算子のオペランドは、他の式または一次式である場合があります (例: 1 + 2 * 3 において、operator+ のオペランドは部分式 2 * 3 と一次式 1 です)。
一次式は、以下のいずれかです
-
this - リテラル (例: 2 や "Hello, world")
- 識別子式、以下を含みます
- 適切に宣言された非修飾識別子 (例: n や cout)、
- 適切に宣言された修飾識別子 (例: std::string::npos)、および
- 宣言子で宣言される識別子
| (C++26以降) |
| (C++11以降) | |
| (C++17以降) | |
| (C++20以降) |
括弧で囲まれた任意の式も一次式として分類されます。これにより、括弧がどの演算子よりも高い優先順位を持つことが保証されます。括弧は値、型、値カテゴリを保持します。
[編集] リテラル
リテラルは、ソースコードに埋め込まれた定数値を表すC++プログラムのトークンです。
- char または wchar_t
|
(C++11以降) |
|
(C++20以降) |
- const char[] または const wchar_t[]
|
(C++11以降) |
|
(C++20以降) |
- ブーリアンリテラルは、bool 型の値、すなわち true と false です
|
(C++11以降) |
[編集] 完全な式
構成式 (constituent expression) は、以下のように定義されます
- 式の構成式とは、その式自身です。
- 波括弧で囲まれた初期化子リストまたは(括弧で囲まれている可能性のある)式リストの構成式は、それぞれのリストの要素の構成式です。
=で始まる初期化子の構成式は、initializer-clause の構成式です。
int num1 = 0; num1 += 1; // Case 1: the constituent expression of “num += 1” is “num += 1” int arr2[2] = {2, 22} // Case 2: the constituent expressions // of “{2, 22}” are “2” and “22” // Case 3: the constituent expressions of “= {2, 22}” // are the constituent expressions of “{2, 22}” // (i.e. also “2” and “22”)
式 E の 直接の部分式 (immediate subexpressions) は、
- E のオペランドの構成式、
|
(C++14以降) |
|
(C++11以降) |
- E が暗黙的に呼び出す任意の関数呼び出し、または
- E が関数呼び出しであるか、関数を暗黙的に呼び出す場合、その呼び出しで使用される各デフォルト引数の構成式。
式 E の 部分式 (subexpression) は、E の直接の部分式、または E の直接の部分式の部分式です。ラムダ式の「関数本体」に現れる式は、そのラムダ式の部分式ではないことに注意してください。(C++11以降)
以下の式は 完全な式 (full-expressions) です
| (C++20以降) |
|
(C++26以降) |
- 他のどの式の部分式でもなく、他のどの完全な式の一部でもない式
言語構成要素が関数の暗黙的な呼び出しを生成するように定義されている場合、その言語構成要素の使用はこの定義の目的上、式と見なされます。式が現れる言語構成要素の要件を満たすために式の結果に適用される変換も、完全な式の一部と見なされます。
初期化子については、エンティティの初期化を実行すること (集成体のデフォルトメンバ初期化子の評価を含む)(C++14以降) も完全な式の一部と見なされます。
[編集] 評価されうる式
|
式は、以下の場合を除き、評価されうる (potentially evaluated) とされます |
(C++11まで) | ||
|
以下のオペランドは 評価されないオペランド (unevaluated operands) であり、評価されません
式は、以下の場合を除き、評価されうる (potentially evaluated) とされます
|
(C++11以降) |
評価されうる式は、ODR-use されます。
| このセクションは未完成です 理由: 評価されないオペランドの例 |
[編集] 値を捨てる式
値を捨てる式 (discarded-value expression) とは、副作用のためだけに使用される式のことです。そのような式から計算された値は捨てられます。これには、任意の式文の完全な式、組み込みコンマ演算子の左オペランド、または型 void へのキャスト式が含まれます。
配列からポインタへ、および関数からポインタへの変換は、値を捨てる式によって計算された値には決して適用されません。左辺値から右辺値への変換が適用されるのは、式がvolatile修飾された glvalue であり、かつ以下のいずれかの形式(組み込みの意味が必要、括弧で囲まれている可能性あり)である場合に限られます
- id-expression、
- 配列添字式、
- クラスメンバアクセス式、
- 間接参照、
- メンバへのポインタ操作、
- 第2オペランドと第3オペランドの両方がこれらの式のいずれかである条件式、
- 右オペランドがこれらの式のいずれかであるコンマ式。
さらに、左辺値が volatile 修飾されたクラス型である場合、結果の右辺値一時オブジェクトを初期化するために volatile コピーコンストラクタが必要です。
|
式が非voidのprvalueである場合(左辺値から右辺値への変換が行われた後)、一時オブジェクトの具体化が発生します。 コンパイラは、void へのキャスト以外の式が |
(C++17以降) |
式の等価性複数の式 e1, e2, ..., eN は、以下の条件がすべて満たされる場合に 式として等価 (expression-equivalent) です e1 が e2 に 式として等価である (expression-equivalent to) とは、e1 と e2 が式として等価である場合に限られます(これは e2 もまた e1 に式として等価であることを意味します)。 |
(C++20以降) |
[編集] 欠陥報告
以下の動作変更を伴う欠陥報告が、以前に公開されたC++標準に遡って適用されました。
| DR | 適用対象 | 公開された動作 | 正しい動作 |
|---|---|---|---|
| CWG 1054 | C++98 | volatile変数への値の代入が、 代入結果に適用される左辺値から 右辺値への変換により、不必要な読み取りを引き起こす可能性があった |
値を捨てる式を導入し このケースをリストから除外 変換が必要なケース |
| CWG 1343 | C++98 | 集成体初期化におけるデストラクタ呼び出しの シーケンスが不十分に規定されていた |
集成体初期化における完全な式が 明確に規定された |
| CWG 1383 | C++98 | 値を捨てる式に左辺値から右辺値への変換が 適用される式のリストが オーバーロードされた演算子も対象としていた |
演算子のみを対象とする 組み込みの意味を持つものに限定 |
| CWG 1576 | C++11 | 値を捨てる volatile xvalue 式に 左辺値から右辺値への変換が適用されていなかった |
変換を適用 この場合に |
| CWG 2249 | C++98 | 宣言子で宣言される識別子が id-expressionではなかった |
現在は |
| CWG 2431 | C++11 | 参照に束縛された一時オブジェクトの デストラクタの呼び出しが完全な式ではなかった |
現在は |
[編集] 関連項目
| C言語のドキュメント Expressions
|