名前空間
変種
操作

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

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

式 (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 += b
a -= b
a *= b
a /= b
a %= b
a &= b
a |= b
a ^= b
a <<= b
a >>= b

++a
--a
a++
a--

+a
-a
a + b
a - b
a * b
a / b
a % b
~a
a & b
a | b
a ^ b
a << b
a >> b

!a
a && b
a || b

a == b
a != b
a < b
a > b
a <= b
a >= b
a <=> b

a[...]
*a
&a
a->b
a.b
a->*b
a.*b

関数呼び出し

a(...)
コンマ

a, b
conditional

a ? b : c
特殊な演算子

static_cast はある型を別の関連する型に変換します
dynamic_cast は継承階層内で変換します
const_castcv修飾子を追加または削除します
reinterpret_cast は型を関連のない型に変換します
Cスタイルキャストstatic_castconst_castreinterpret_cast の組み合わせによってある型を別の型に変換します
new は動的ストレージ期間を持つオブジェクトを生成します
delete は new 式によって以前に作成されたオブジェクトを破棄し、取得したメモリ領域を解放します
sizeof は型のサイズを問い合わせます
sizeof...パックのサイズを問い合わせます (C++11以降)
typeid は型の型情報を問い合わせます
noexcept は式が例外を投げる可能性があるかどうかをチェックします (C++11以降)
alignof は型のアライメント要求を問い合わせます (C++11以降)

[編集] 変換

[編集] メモリ確保

  • new 式 メモリを動的に確保します
  • delete 式 メモリを動的に解放します

[編集] その他

  • 定数式 コンパイル時に評価でき、コンパイル時のコンテキスト (テンプレート引数、配列サイズなど) で使用できます
  • sizeof
  • alignof
  • typeid
  • throw式

[編集] 一次式

任意の演算子のオペランドは、他の式または一次式である場合があります (例: 1 + 2 * 3 において、operator+ のオペランドは部分式 2 * 3 と一次式 1 です)。

一次式は、以下のいずれかです

(C++26以降)
(C++11以降)
(C++17以降)
(C++20以降)

括弧で囲まれた任意の式も一次式として分類されます。これにより、括弧がどの演算子よりも高い優先順位を持つことが保証されます。括弧は値、型、値カテゴリを保持します。

[編集] リテラル

リテラルは、ソースコードに埋め込まれた定数値を表すC++プログラムのトークンです。

  • char または wchar_t
  • char16_t または char32_t
(C++11以降)
  • char8_t
(C++20以降)
  • const char[] または const wchar_t[]
  • const char16_t[] または const char32_t[]
(C++11以降)
  • const char8_t[]
(C++20以降)
(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以降)
  • Eラムダ式である場合、コピーによってキャプチャされたエンティティの初期化、およびキャプチャの初期化子の構成式、
(C++11以降)
  • E が暗黙的に呼び出す任意の関数呼び出し、または
  • E が関数呼び出しであるか、関数を暗黙的に呼び出す場合、その呼び出しで使用される各デフォルト引数の構成式。

E部分式 (subexpression) は、E の直接の部分式、または E の直接の部分式の部分式です。ラムダ式の「関数本体」に現れる式は、そのラムダ式の部分式ではないことに注意してください。(C++11以降)

以下の式は 完全な式 (full-expressions) です

(C++20以降)
(C++26以降)
  • 他のどの式の部分式でもなく、他のどの完全な式の一部でもない式

言語構成要素が関数の暗黙的な呼び出しを生成するように定義されている場合、その言語構成要素の使用はこの定義の目的上、式と見なされます。式が現れる言語構成要素の要件を満たすために式の結果に適用される変換も、完全な式の一部と見なされます。

初期化子については、エンティティの初期化を実行すること (集成体のデフォルトメンバ初期化子の評価を含む)(C++14以降) も完全な式の一部と見なされます。

[編集] 評価されうる式

式は、以下の場合を除き、評価されうる (potentially evaluated) とされます

  • それが sizeof 演算子のオペランドである場合、または
  • それが typeid 演算子のオペランドであり、多相クラス型の左辺値 (lvalue) を指定しない場合。
(C++11まで)

以下のオペランドは 評価されないオペランド (unevaluated operands) であり、評価されません

  • 多相クラス型の glvalue を除き、typeid 演算子が適用される式
  • sizeof 演算子のオペランドである式
  • noexcept 演算子のオペランド
  • decltype 指定子のオペランド
(C++20以降)

式は、以下の場合を除き、評価されうる (potentially evaluated) とされます

  • それが評価されないオペランドである場合、または
  • それが評価されないオペランドの部分式である場合。
(C++11以降)

評価されうる式は、ODR-use されます。

[編集] 値を捨てる式

値を捨てる式 (discarded-value expression) とは、副作用のためだけに使用される式のことです。そのような式から計算された値は捨てられます。これには、任意の式文の完全な式、組み込みコンマ演算子の左オペランド、または型 void へのキャスト式が含まれます。

配列からポインタへ、および関数からポインタへの変換は、値を捨てる式によって計算された値には決して適用されません。左辺値から右辺値への変換が適用されるのは、式がvolatile修飾された glvalue であり、かつ以下のいずれかの形式(組み込みの意味が必要、括弧で囲まれている可能性あり)である場合に限られます

  • id-expression、
  • 配列添字式、
  • クラスメンバアクセス式、
  • 間接参照、
  • メンバへのポインタ操作、
  • 第2オペランドと第3オペランドの両方がこれらの式のいずれかである条件式、
  • 右オペランドがこれらの式のいずれかであるコンマ式。

さらに、左辺値が volatile 修飾されたクラス型である場合、結果の右辺値一時オブジェクトを初期化するために volatile コピーコンストラクタが必要です。

式が非voidのprvalueである場合(左辺値から右辺値への変換が行われた後)、一時オブジェクトの具体化が発生します。

コンパイラは、void へのキャスト以外の式が [[nodiscard]] と宣言された値を捨てる場合に警告を発することがあります。

(C++17以降)

式の等価性

複数の式 e1, e2, ..., eN は、以下の条件がすべて満たされる場合に 式として等価 (expression-equivalent) です

  1. それらは同じ効果を持ちます。
  2. それらがすべて定数部分式であるか、またはどれもそうでないかのいずれかです。
  3. それらがすべてnoexceptであるか、またはどれもそうでないかのいずれかです。

e1e2式として等価である (expression-equivalent to) とは、e1e2 が式として等価である場合に限られます(これは 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 参照に束縛された一時オブジェクトの
デストラクタの呼び出しが完全な式ではなかった
現在は

[編集] 関連項目

English 日本語 中文(简体) 中文(繁體)