Assignment operators modify the value of the object.
Operator name Syntax
Prototype examples (for classT) Inside class definition Outside class definition simple assignment a = bYes T&T::operator=(constT2&b);N/Aaddition assignment a += bYes T&T::operator+=(constT2&b);T&operator+=(T&a,constT2&b);subtraction assignment a -= bYes T&T::operator-=(constT2&b);T&operator-=(T&a,constT2&b);multiplication assignment a *= bYes T&T::operator*=(constT2&b);T&operator*=(T&a,constT2&b);division assignment a /= bYes T&T::operator/=(constT2&b);T&operator/=(T&a,constT2&b);remainder assignment a %= bYes T&T::operator%=(constT2&b);T&operator%=(T&a,constT2&b);bitwise AND assignment a &= bYes T&T::operator&=(constT2&b);T&operator&=(T&a,constT2&b);bitwise OR assignment a |= bYes T&T::operator|=(constT2&b);T&operator|=(T&a,constT2&b);bitwise XOR assignment a ^= bYes T&T::operator^=(constT2&b);T&operator^=(T&a,constT2&b);bitwise left shift assignment a <<= bYes T&T::operator<<=(constT2&b);T&operator<<=(T&a,constT2&b);bitwise right shift assignment a >>= bYes T&T::operator>>=(constT2&b);T&operator>>=(T&a,constT2&b);Notes
All built-in assignment operators return *this, and most
also return *this so that the user-defined operators can be used in the same manner as the built-ins. However, in a user-defined operator overload, any type can be used as return type (including void).
T2 can be any type including T.
Definitions
Copy assignment replaces the contents of the object a with a copy of the contents of b (b is not modified). For class types, this is performed in a special member function, described in
.
Move assignment replaces the contents of the object a with the contents of b, avoiding copying if possible (b may be modified). For class types, this is performed in a special member function, described in
.
(since C++11)For non-class types, copy and move assignment are indistinguishable and are referred to as direct assignment.
Compound assignment replace the contents of the object a with the result of a binary operation between the previous value of a and the value of b.
Assignment operator syntax
The assignment expressions have the form
target-expr=new-value(1) target-expr op new-value(2) target-expr- the expression
to be assigned to op- one of *=, /=%=, +=-=, <<=, >>=, &=, ^=, |=new-value- the expression
(until C++11)
(since C++11) to assign to the target
target-expr must have higher
than an assignment expression.
new-value cannot be a comma expression, because its
is lower.
1) Simple assignment expression.
2) Compound assignment expression.
If new-value is not an expression, the assignment expression will never match an overloaded compound assignment operator.
(since C++11)Built-in simple assignment operator
For the built-in simple assignment, target-expr must be a modifiable lvalue.
The object referred to by target-expr is modified by replacing its value with the result of new-value. If the object referred is of an integer type T, and the result of new-value is of the corresponding signed/unsigned integer type, the value of the object is replaced with the value of type T with the same value representation of the result of new-value.
The result of a built-in simple assignment is an lvalue of the type of target-expr, referring to target-expr. If target-expr is a
, the result is also a bit-field.
Assignment from an expression
If new-value is an expression, it is
to the cv-unqualified type of target-expr. When target-expr is a bit-field that cannot represent the value of the expression, the resulting value of the bit-field is implementation-defined.
If target-expr and new-value identify overlapping objects, the behavior is undefined (unless the overlap is exact and the type is the same).
Assignment from a non-expression initializer clause
new-value is only allowed not to be an expression in following situations:
target-expr is of a
T, and new-value is empty or has only one element. In this case, given an invented variable t declared and initialized as Tt=new-value, the meaning of x=new-value is x=t.
target-expr is of class type. In this case, new-value is passed as the argument to the assignment operator function selected by
.
#include<complex>std::complex<double>z;z={1,2};// meaning z.operator=({1, 2})z+={1,2};// meaning z.operator+=({1, 2})inta,b;a=b={1};// meaning a = b = 1;a={1}=b;// syntax error(since C++11)In
overload resolution against user-defined operators
, for every type T, the following function signatures participate in overload resolution:
T*&operator=(T*&,T*);T*volatile&operator=(T*volatile&,T*);For every enumeration or pointer to member type T, optionally volatile-qualified, the following function signature participates in overload resolution:
T&operator=(T&,T);For every pair A1 and A2, where A1 is an arithmetic type (optionally volatile-qualified) and A2 is a promoted arithmetic type, the following function signature participates in overload resolution:
A1&operator=(A1&,A2);Built-in compound assignment operator
The behavior of every built-in compound-assignment expression target-exprop=new-value is exactly the same as the behavior of the expression target-expr=target-expropnew-value, except that target-expr is evaluated only once.
The requirements on target-expr and new-value of built-in simple assignment operators also apply. Furthermore:
For += and -=, the type of target-expr must be an
or a pointer to a (possibly cv-qualified) completely-defined
.
For all other compound assignment operators, the type of target-expr must be an arithmetic type.
In
overload resolution against user-defined operators
, for every pair A1 and A2, where A1 is an arithmetic type (optionally volatile-qualified) and A2 is a promoted arithmetic type, the following function signatures participate in overload resolution:
A1&operator*=(A1&,A2);A1&operator/=(A1&,A2);A1&operator+=(A1&,A2);A1&operator-=(A1&,A2);For every pair I1 and I2, where I1 is an integral type (optionally volatile-qualified) and I2 is a promoted integral type, the following function signatures participate in overload resolution:
I1&operator%=(I1&,I2);I1&operator<<=(I1&,I2);I1&operator>>=(I1&,I2);I1&operator&=(I1&,I2);I1&operator^=(I1&,I2);I1&operator|=(I1&,I2);For every optionally cv-qualified object type T, the following function signatures participate in overload resolution:
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);Example
Run this code
#include<iostream>intmain(){intn=0;// not an assignmentn=1;// direct assignmentstd::cout<<n<<' ';n={};// zero-initialization, then assignmentstd::cout<<n<<' ';n='a';// integral promotion, then assignmentstd::cout<<n<<' ';n={'b'};// explicit cast, then assignmentstd::cout<<n<<' ';n=1.0;// floating-point conversion, then assignmentstd::cout<<n<<' ';// n = {1.0}; // compiler error (narrowing conversion)int&r=n;// not an assignmentr=2;// assignment through referencestd::cout<<n<<' ';int*p;p=&n;// direct assignmentp=nullptr;// null-pointer conversion, then assignmentstd::cout<<p<<' ';struct{inta;std::strings;}obj;obj={1,"abc"};// assignment from a braced-init-liststd::cout<<obj.a<<':'<<obj.s<<'\n';}Possible output:
1 0 97 98 1 2 (nil) 1:abc Defect reports
The following behavior-changing defect reports were applied retroactively to previously published C++ standards.
DR Applied to Behavior as published Correct behavior
C++11 for assignments to class type objects, the right operand
could be an initializer list only when the assignment
is defined by a user-defined assignment operator removed user-defined
assignment constraint
C++11 E1={E2} was equivalent to E1=T(E2)
(T is the type of E1), this introduced a C-style cast it is equivalent
to E1=T{E2}
C++20 compound assignment operators for volatile
-qualified types were inconsistently deprecated none of them
is deprecated
C++11 an assignment from a non-expression initializer clause
to a scalar value would perform direct-list-initialization performs copy-list-
initialization instead
C++98 the value assigned to an unsignedint
object through an int lvalue is unclear made clear
C++20 bitwise compound assignment operators for volatile types
were deprecated while being useful for some platforms they are not
deprecated See also
Common operators
a=ba+=ba-=ba*=ba/=ba%=ba&=ba|=ba^=ba<<=ba>>=b++a--aa++a--+a-aa+ba-ba*ba/ba%b~aa&ba|ba^ba<<ba>>b!aa&&ba||ba==ba!=ba<ba>ba<=ba>=ba<=>ba[...]*a&aa->ba.ba->*ba.*bfunction calla(...)
commaa,b
conditionala?b:c
Special operators
converts one type to another related type
converts within inheritance hierarchies
adds or removes
-qualifiers
converts type to unrelated type
converts one type to another by a mix of static_cast, const_cast, and reinterpret_cast
creates objects with dynamic storage duration
destructs objects previously created by the new expression and releases obtained memory area
queries the size of a type
queries the size of a
(since C++11)
queries the type information of a type
checks if an expression can throw an exception (since C++11)
queries alignment requirements of a type (since C++11)
produces a reflection value from a grammatical construct (since C++26)