Assignment operators
代入演算子はオブジェクトの値を変更します。
| 演算子名 | 構文 | オーバーロード可否 | プロトタイプ例 ( class T の場合) | |
|---|---|---|---|---|
| クラス定義内 | クラス定義外 | |||
| 単純代入 |
a = b
|
可 | T & T :: operator = ( const T2 & b ) ; | 該当なし |
| 加算代入 |
a += b
|
可 | T & T :: operator + = ( const T2 & b ) ; | T & operator + = ( T & a, const T2 & b ) ; |
| 減算代入 |
a -= b
|
可 | T & T :: operator - = ( const T2 & b ) ; | T & operator - = ( T & a, const T2 & b ) ; |
| 乗算代入 |
a *= b
|
Yes | T & T :: operator * = ( const T2 & b ) ; | T & operator * = ( T & a, const T2 & b ) ; |
| 除算代入 |
a /= b
|
可 | T & T :: operator / = ( const T2 & b ) ; | T & operator / = ( T & a, const T2 & b ) ; |
| 剰余代入 |
a %= b
|
可 | T & T :: operator % = ( const T2 & b ) ; | T & operator % = ( T & a, const T2 & b ) ; |
| ビット単位AND代入 |
a &= b
|
可 | T & T :: operator & = ( const T2 & b ) ; | T & operator & = ( T & a, const T2 & b ) ; |
| ビット単位OR代入 |
a |= b
|
可 | T & T :: operator | = ( const T2 & b ) ; | T & operator | = ( T & a, const T2 & b ) ; |
| ビット単位XOR代入 |
a ^= b
|
可 | T & T :: operator ^ = ( const T2 & b ) ; | T & operator ^ = ( T & a, const T2 & b ) ; |
| ビット単位左シフト代入 |
a <<= b
|
可 | T & T :: operator <<= ( const T2 & b ) ; | T & operator <<= ( T & a, const T2 & b ) ; |
| ビット単位右シフト代入 |
a >>= b
|
可 | T & T :: operator >>= ( const T2 & b ) ; | T & operator >>= ( T & a, const T2 & b ) ; |
|
||||
目次 |
定義
コピー代入 はオブジェクト a の内容を b の内容のコピーで置き換えます( b は変更されません)。クラス型の場合、これは特別なメンバ関数で実行され、 コピー代入演算子 で説明されています。
|
ムーブ代入 は、可能な場合はコピーを避けつつ、オブジェクト a の内容を b の内容で置き換える( b は変更される可能性がある)。クラス型の場合、これは特別なメンバ関数で実行され、 ムーブ代入演算子 で説明されている。 |
(C++11以降) |
非クラス型の場合、コピー代入とムーブ代入は区別がつかず、 direct assignment と呼ばれます。
複合代入 は、オブジェクト a の内容を、 a の以前の値と b の値との二項演算の結果で置き換えます。
代入演算子の構文
代入式は以下の形式を持ちます
target-expr
=
new-value
|
(1) | ||||||||
| target-expr op new-value | (2) | ||||||||
| target-expr | - | 代入対象の式 [1] |
| op | - | 以下のいずれか * = , / = % = , + = - = , <<= , >>= , & = , ^ = , | = |
| new-value | - | ターゲットに代入する 式 [2] (C++11まで) 初期化子節 (C++11以降) |
|
new-value が式でない場合、代入式はオーバーロードされた複合代入演算子にマッチすることはありません。 |
(C++11以降) |
組み込み単純代入演算子
組み込みの単純代入において、 target-expr は変更可能な左値でなければなりません。
target-expr
によって参照されるオブジェクトは、その値が
new-value
の結果で置き換えられることによって変更されます。参照されるオブジェクトが整数型
T
であり、
new-value
の結果が対応する符号付き/符号なし整数型である場合、オブジェクトの値は
new-value
の結果と同じ値表現を持つ型
T
の値で置き換えられます。
組み込みの単純代入の結果は、 target-expr の型の左辺値であり、 target-expr を参照します。 target-expr が ビットフィールド である場合、結果もビットフィールドとなります。
式からの代入
new-value が式である場合、それは 暗黙変換 され、 target-expr のCV修飾されていない型に変換されます。 target-expr が式の値を表現できないビットフィールドである場合、ビットフィールドの結果の値は実装定義となります。
target-expr と new-value が重複するオブジェクトを識別する場合、動作は未定義です(ただし、重複が正確で型が同じである場合を除く)。
|
target-expr の型がvolatile修飾されている場合、代入は非推奨となります。ただし、(括弧で囲まれている可能性のある)代入式が 破棄値式 または 未評価オペランド である場合は除きます。 |
(C++20以降) |
非式初期化子句からの代入new-value が式でないことが許容されるのは以下の状況のみです:
#include <complex> std::complex<double> z; z = {1, 2}; // meaning z.operator=({1, 2}) z += {1, 2}; // meaning z.operator+=({1, 2}) int a, b; a = b = {1}; // meaning a = b = 1; a = {1} = b; // syntax error |
(C++11以降) |
ユーザー定義演算子に対するオーバーロード解決
において、あらゆる型
T
に対して、以下の関数シグネチャがオーバーロード解決に参加します:
|
T
*
&
operator
=
(
T
*
&
, T
*
)
;
|
||
|
T
*
volatile
&
operator
=
(
T
*
volatile
&
, T
*
)
;
|
||
すべての列挙型またはメンバへのポインタ型
T
について(オプションでvolatile修飾されたものも含む)、以下の関数シグネチャはオーバーロード解決に参加します:
|
T
&
operator
=
(
T
&
, T
)
;
|
||
すべてのペア
A1
と
A2
について、
A1
が算術型(volatile修飾されている可能性もある)であり、
A2
が昇格された算術型である場合、以下の関数シグネチャがオーバーロード解決に参加します:
|
A1
&
operator
=
(
A1
&
, A2
)
;
|
||
組み込み複合代入演算子
すべての組み込み複合代入式
target-expr
op
=
new-value
の動作は、式
target-expr
=
target-expr
op
new-value
の動作と完全に同一ですが、
target-expr
が一度だけ評価される点が異なります。
組み込みの単純代入演算子に対する target-expr と new-value の要件も適用されます。さらに:
-
+=および-=の場合、 target-expr の型は 算術型 または(cv修飾された可能性のある)完全に定義された オブジェクト型 へのポインタでなければなりません。 - その他の複合代入演算子の場合、 target-expr の型は算術型でなければなりません。
ユーザ定義演算子に対する
オーバーロード解決
において、
A1
と
A2
の各ペアについて(ここで
A1
は算術型(オプションでvolatile修飾可能)、
A2
は昇格された算術型)、以下の関数シグネチャがオーバーロード解決に参加します:
|
A1
&
operator
*
=
(
A1
&
, A2
)
;
|
||
|
A1
&
operator
/
=
(
A1
&
, A2
)
;
|
||
|
A1
&
operator
+
=
(
A1
&
, A2
)
;
|
||
|
A1
&
operator
-
=
(
A1
&
, A2
)
;
|
||
すべてのペア
I1
と
I2
について、
I1
が整数型(オプションでvolatile修飾可能)であり、
I2
がプロモートされた整数型である場合、以下の関数シグネチャがオーバーロード解決に参加します:
|
I1
&
operator
%
=
(
I1
&
, I2
)
;
|
||
|
I1
&
operator
<<=
(
I1
&
, I2
)
;
|
||
|
I1
&
operator
>>=
(
I1
&
, I2
)
;
|
||
|
I1
&
operator
&
=
(
I1
&
, I2
)
;
|
||
|
I1
&
operator
^
=
(
I1
&
, I2
)
;
|
||
|
I1
&
operator
|
=
(
I1
&
, I2
)
;
|
||
任意のオプションでcv修飾されたオブジェクト型
T
に対して、以下の関数シグネチャがオーバーロード解決に参加します:
|
T
*
&
operator
+
=
(
T
*
&
,
std::
ptrdiff_t
)
;
|
||
|
T
*
&
operator
-
=
(
T
*
&
,
std::
ptrdiff_t
)
;
|
||
|
T
*
volatile
&
operator
+
=
(
T
*
volatile
&
,
std::
ptrdiff_t
)
;
|
||
|
T
*
volatile
&
operator
-
=
(
T
*
volatile
&
,
std::
ptrdiff_t
)
;
|
||
`/`
`/`
例
#include <iostream> int main() { int n = 0; // 代入ではない n = 1; // 直接代入 std::cout << n << ' '; n = {}; // ゼロ初期化後の代入 std::cout << n << ' '; n = 'a'; // 整数昇格後の代入 std::cout << n << ' '; n = {'b'}; // 明示的キャスト後の代入 std::cout << n << ' '; n = 1.0; // 浮動小数点変換後の代入 std::cout << n << ' '; // n = {1.0}; // コンパイルエラー(縮小変換) int& r = n; // 代入ではない r = 2; // 参照を通した代入 std::cout << n << ' '; int* p; p = &n; // 直接代入 p = nullptr; // ヌルポインタ変換後の代入 std::cout << p << ' '; struct { int a; std::string s; } obj; obj = {1, "abc"}; // 波括弧初期化リストからの代入 std::cout << obj.a << ':' << obj.s << '\n'; }
出力例:
1 0 97 98 1 2 (nil) 1:abc
不具合報告
以下の動作変更の欠陥報告書は、以前に公開されたC++規格に対して遡及的に適用されました。
| DR | 適用対象 | 公開時の動作 | 正しい動作 |
|---|---|---|---|
| CWG 1527 | C++11 |
クラス型オブジェクトへの代入において、右オペランド
はユーザー定義代入演算子で定義された代入の場合にのみ 初期化子リストを使用可能であった |
ユーザー定義代入の
制約を削除 |
| CWG 1538 | C++11 |
E1
=
{
E2
}
は
E1
=
T
(
E2
)
と等価であった
(
T
は
E1
の型)、これはCスタイルキャストを導入していた
|
これは
E1 = T { E2 } と等価 |
| CWG 2654 | C++20 |
volatile修飾型に対する複合代入演算子の
非推奨化が一貫していなかった |
いずれも
非推奨ではない |
| CWG 2768 | C++11 |
非式初期化句からスカラー値への代入は
直接リスト初期化を実行していた |
代わりにコピーリスト
初期化を実行 |
| CWG 2901 | C++98 |
int
左辺値を通じて
unsigned
int
オブジェクトに
代入される値が不明確であった |
明確化された |
| P2327R1 | C++20 |
volatile型に対するビット単位複合代入演算子が
一部プラットフォームで有用であるにもかかわらず非推奨とされていた |
これらは
非推奨ではない |
関連項目
| 共通演算子 | ||||||
|---|---|---|---|---|---|---|
| 代入 |
インクリメント
デクリメント |
算術 | 論理 | 比較 |
メンバー
アクセス |
その他 |
|
a
=
b
|
++
a
|
+
a
|
!
a
|
a
==
b
|
a
[
...
]
|
関数呼び出し
a ( ... ) |
|
カンマ
a, b |
||||||
|
条件演算子
a ? b : c |
||||||
| 特殊演算子 | ||||||
|
static_cast
関連する型間での変換を行う
|
||||||
|
C documentation
for
Assignment operators
|