名前空間
変種
操作

代入演算子

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

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

代入演算子はオブジェクトの値を変更します。

演算子名  構文  オーバーロード可能 プロトタイプの例 (class T の場合)
クラス定義内 クラス定義外
単純代入 a = b はい T& T::operator =(const T2& b); N/A
加算代入 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 はい 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);
注釈
  • すべての組み込み代入演算子は *this を返します。また、ほとんどの ユーザー定義オーバーロード*this を返すため、ユーザー定義演算子は組み込み演算子と同様に使用できます。ただし、ユーザー定義演算子オーバーロードでは、void を含む任意の型を戻り値として使用できます。
  • T2T を含む任意の型にすることができます。

目次

[編集] 定義

コピー代入は、オブジェクト a の内容を b の内容のコピーで置き換えます(b は変更されません)。クラス型の場合、これは特殊メンバ関数によって実行され、「コピー代入演算子」で説明されています。

ムーブ代入は、オブジェクト a の内容を b の内容で置き換えます。可能であればコピーを回避します(b は変更される場合があります)。クラス型の場合、これは特殊メンバ関数によって実行され、「ムーブ代入演算子」で説明されています。

(C++11以降)

非クラス型の場合、コピー代入とムーブ代入は区別がつかず、直接代入と呼ばれます。

複合代入は、オブジェクト 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以降)
  1. target-expr は、代入式の 演算子の優先度よりも高い必要があります。
  2. new-value はカンマ式にできません。その 演算子の優先度が低いためです。
1) 単純代入式。
2) 複合代入式。

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 が式の値を表現できないビットフィールドである場合、ビットフィールドのresulting値は実装定義です。

target-exprnew-value が重複するオブジェクトを識別する場合、動作は未定義です(重複が完全で型が同じである場合を除く)。

target-expr の型が volatile 修飾されている場合、代入は非推奨です。ただし、(必要に応じて括弧で囲まれた)代入式が 破棄値式 または 評価対象外オペランドである場合を除きます。

(C++20以降)


初期化子句(式でない)からの代入

new-value が式でないことが許可されるのは、次の状況のみです。

  • target-exprスカラー型 T であり、new-value が空または要素が1つだけの場合。この場合、架空の変数 tT t = new-value  と宣言および初期化されていると仮定すると、x = new-value  の意味は x = t です。
  • target-expr がクラス型の場合。この場合、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);

すべてのペア A1A2 について、ここで 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 の型は算術型である必要があります。

ユーザー定義演算子に対するオーバーロード解決では、すべてのペア A1A2 について、ここで A1 は算術型(オプションで volatile 修飾可能)であり、A2 は昇格された算術型である場合、次の関数シグネチャがオーバーロード解決に参加します。

A1& operator*=(A1&, A2);
A1& operator/=(A1&, A2);
A1& operator+=(A1&, A2);
A1& operator-=(A1&, A2);

すべてのペア I1I2 について、ここで 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;        // not an assignment
 
    n = 1;            // direct assignment
    std::cout << n << ' ';
 
    n = {};           // zero-initialization, then assignment
    std::cout << n << ' ';
 
    n = 'a';          // integral promotion, then assignment
    std::cout << n << ' ';
 
    n = {'b'};        // explicit cast, then assignment
    std::cout << n << ' ';
 
    n = 1.0;          // floating-point conversion, then assignment
    std::cout << n << ' ';
 
//  n = {1.0};        // compiler error (narrowing conversion)
 
    int& r = n;       // not an assignment
    r = 2;            // assignment through reference
    std::cout << n << ' ';
 
    int* p;
    p = &n;           // direct assignment
    p = nullptr;      // null-pointer conversion, then assignment
    std::cout << p << ' ';
 
    struct { int a; std::string s; } obj;
    obj = {1, "abc"}; // assignment from a braced-init-list
    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) に等価でした
(TE1 の型)、これは C スタイルのキャストを導入しました。
等価になりました
E1 = T{E2}
CWG 2654 C++20 volatile 修飾された型の複合代入演算子は、一貫性がなく非推奨でした。
それらの none
は非推奨です。
非推奨です。
CWG 2768 C++11 式でない初期化子句からの
スカラー値への代入は、直接リスト初期化を実行していました。
コピーリスト
初期化を実行します。
CWG 2901 C++98 int 左辺値を通じた unsigned int
オブジェクトへの代入は不明瞭です。
明確化された
P2327R1 C++20 volatile 型のビット単位複合代入演算子
一部のプラットフォームで有用でありながら非推奨になりました。
ならない
deprecated

[編集] 関連項目

演算子の優先順位

演算子のオーバーロード

共通の演算子
代入 インクリメント
デクリメント
算術 論理 比較 メンバ
アクセス
その他

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

C ドキュメント代入演算子
English 日本語 中文(简体) 中文(繁體)