A copy assignment operator is eligible if
, if any, are satisfied, and than it.Triviality of eligible copy assignment operators determines whether the class is a trivially copyable type .
If the implicitly-declared copy assignment operator is neither deleted nor trivial, it is defined (that is, a function body is generated and compiled) by the compiler if odr-used or needed for constant evaluation (since C++14) . For union types, the implicitly-defined copy assignment copies the object representation (as by std::memmove ). For non-union class types ( class and struct ), the operator performs member-wise copy assignment of the object's bases and non-static members, in their initialization order, using built-in assignment for the scalars and copy assignment operator for class types.
The implicitly-defined copy assignment operator for a class is if is a , and that is of class type (or array thereof), the assignment operator selected to copy that member is a constexpr function. | (since C++14) (until C++23) |
The implicitly-defined copy assignment operator for a class is . | (since C++23) |
The generation of the implicitly-defined copy assignment operator is deprecated if has a user-declared destructor or user-declared copy constructor. | (since C++11) |
If both copy and move assignment operators are provided, overload resolution selects the move assignment if the argument is an rvalue (either a prvalue such as a nameless temporary or an xvalue such as the result of std::move ), and selects the copy assignment if the argument is an lvalue (named object or a function/operator returning lvalue reference). If only the copy assignment is provided, all argument categories select it (as long as it takes its argument by value or as reference to const, since rvalues can bind to const references), which makes copy assignment the fallback for move assignment, when move is unavailable.
It is unspecified whether virtual base class subobjects that are accessible through more than one path in the inheritance lattice, are assigned more than once by the implicitly-defined copy assignment operator (same applies to move assignment ).
See assignment operator overloading for additional detail on the expected behavior of a user-defined copy-assignment operator.
[ edit ] 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 | a volatile subobject made defaulted copy assignment operators non-trivial ( ) | triviality not affected | |
C++11 | operator=(X&) = default was non-trivial | made trivial | |
C++11 | a defaulted copy assignment operator for class was not defined as deleted if is abstract and has non-copy-assignable direct virtual base classes | the operator is defined as deleted in this case |
(C++20) | ||||
(C++20) | ||||
(C++11) | ||||
(C++11) | ||||
(C++11) | ||||
(C++17) | ||||
General topics | ||||
(C++11) |
- |
-expression |
- block |
(C++11) | ||||
(C++11) | ||||
(C++11) |
/ | ||||
(C++11) |
(C++11) | ||||
Expressions | ||||
expression |
pointer |
specifier |
(C++11) | ||||
(C++11) |
(C++11) | ||||
(C++11) |
(C++11) | ||||
(C++11) |
General | ||||
(lvalue, rvalue, xvalue) | ||||
(sequence points) | ||||
(C++11) | ||||
Literals | ||||
including | ||||
(C++11) | ||||
(C++11) | ||||
Operators | ||||
: , , , , , , , , , , | ||||
: , , , | ||||
: , , , , , , , , , , , , | ||||
: , , | ||||
: , , , , , , (C++20) | ||||
: , , , , , , | ||||
: , , | ||||
(C++20) | ||||
(C++17) | ||||
(C++11) | ||||
(C++11) | ||||
Conversions | ||||
, | ||||
Customizes the C++ operators for operands of user-defined types.
Overloaded operators are functions with special function names:
op | (1) | ||||||||
type | (2) | ||||||||
| (3) | ||||||||
| (4) | ||||||||
suffix-identifier | (5) | (since C++11) | |||||||
op | - | any of the following 38 (until C++20)40 (since C++20) operators:+ - * / % ^ & | ~ ! = < > += -= *= /= %= ^= &= |= << >> >>= <<= == != <= >= <=> (since C++20) && || ++ -- , ->* -> ( ) [ ] co_await (since C++20) |
When an operator appears in an expression , and at least one of its operands has a class type or an enumeration type , then overload resolution is used to determine the user-defined function to be called among all the functions whose signatures match the following:
Expression | As member function | As non-member function | Example |
---|---|---|---|
@a | (a).operator@ ( ) | operator@ (a) | ! calls .operator!() |
a@b | (a).operator@ (b) | operator@ (a, b) | << 42 calls .operator<<(42) |
a=b | (a).operator= (b) | cannot be non-member | s; s = "abc"; calls s.operator=("abc") |
a(b...) | (a).operator()(b...) | cannot be non-member | r; auto n = r(); calls r.operator()() |
a[b] | (a).operator[](b) | cannot be non-member | <int, int> m; m[1] = 2; calls m.operator[](1) |
a-> | (a).operator-> ( ) | cannot be non-member | auto p = <S>(); p->bar() calls p.operator->() |
a@ | (a).operator@ (0) | operator@ (a, 0) | <int>::iterator i = v.begin(); i++ calls i.operator++(0) |
in this table, is a placeholder representing all matching operators: all prefix operators in @a, all postfix operators other than -> in a@, all infix operators other than = in a@b |
Note: for overloading user-defined conversion functions , user-defined literals , allocation and deallocation see their respective articles.
Overloaded operators (but not the built-in operators) can be called using function notation:
, , and (comma) lose their special when overloaded and behave like regular function calls even when they are used without function-call notation. | (until C++17) |
Other than the restrictions above, the language puts no other constraints on what the overloaded operators do, or on the return type (it does not participate in overload resolution), but in general, overloaded operators are expected to behave as similar as possible to the built-in operators: operator + is expected to add, rather than multiply its arguments, operator = is expected to assign, etc. The related operators are expected to behave similarly ( operator + and operator + = do the same addition-like operation). The return types are limited by the expressions in which the operator is expected to be used: for example, assignment operators return by reference to make it possible to write a = b = c = d , because the built-in operators allow that.
Commonly overloaded operators have the following typical, canonical forms: [1]
The assignment operator ( operator = ) has special properties: see copy assignment and move assignment for details.
The canonical copy-assignment operator is expected to perform no action on self-assignment , and to return the lhs by reference:
The canonical move assignment is expected to leave the moved-from object in valid state (that is, a state with class invariants intact), and either do nothing or at least leave the object in a valid state on self-assignment, and return the lhs by reference to non-const, and be noexcept:
In those situations where copy assignment cannot benefit from resource reuse (it does not manage a heap-allocated array and does not have a (possibly transitive) member that does, such as a member std::vector or std::string ), there is a popular convenient shorthand: the copy-and-swap assignment operator, which takes its parameter by value (thus working as both copy- and move-assignment depending on the value category of the argument), swaps with the parameter, and lets the destructor clean it up.
This form automatically provides strong exception guarantee , but prohibits resource reuse.
The overloads of operator>> and operator<< that take a std:: istream & or std:: ostream & as the left hand argument are known as insertion and extraction operators. Since they take the user-defined type as the right argument ( b in a@b ), they must be implemented as non-members.
These operators are sometimes implemented as friend functions .
When a user-defined class overloads the function call operator, operator ( ) , it becomes a FunctionObject type. Many standard algorithms, from std:: sort to std:: accumulate accept objects of such types to customize behavior. There are no particularly notable canonical forms of operator ( ) , but to illustrate the usage
When the postfix increment and decrement appear in an expression, the corresponding user-defined function ( operator ++ or operator -- ) is called with an integer argument 0 . Typically, it is implemented as T operator ++ ( int ) , where the argument is ignored. The postfix increment and decrement operator is usually implemented in terms of the prefix version:
Although canonical form of pre-increment/pre-decrement returns a reference, as with any operator overload, the return type is user-defined; for example the overloads of these operators for std::atomic return by value.
Binary operators are typically implemented as non-members to maintain symmetry (for example, when adding a complex number and an integer, if operator+ is a member function of the complex type, then only complex + integer would compile, and not integer + complex ). Since for every binary arithmetic operator there exists a corresponding compound assignment operator, canonical forms of binary operators are implemented in terms of their compound assignments:
Standard algorithms such as std:: sort and containers such as std:: set expect operator < to be defined, by default, for the user-provided types, and expect it to implement strict weak ordering (thus satisfying the Compare requirements). An idiomatic way to implement strict weak ordering for a structure is to use lexicographical comparison provided by std::tie :
Typically, once operator < is provided, the other relational operators are implemented in terms of operator < .
Likewise, the inequality operator is typically implemented in terms of operator == :
When three-way comparison (such as std::memcmp or std::string::compare ) is provided, all six relational operators may be expressed through that:
All six relational operators are automatically generated by the compiler if the three-way comparison operator operator<=> is defined, and that operator, in turn, is generated by the compiler if it is defined as defaulted: Record { name; unsigned int floor; double weight; auto operator<=>(const Record&) = default; }; // records can now be compared with ==, !=, <, <=, >, and >=See for details. | (since C++20) |
User-defined classes that provide array-like access that allows both reading and writing typically define two overloads for operator [ ] : const and non-const variants:
If the value type is known to be a built-in type, the const variant should return by value.
Where direct access to the elements of the container is not wanted or not possible or distinguishing between lvalue c [ i ] = v ; and rvalue v = c [ i ] ; usage, operator[] may return a proxy. see for example std::bitset::operator[] .
To provide multidimensional array access semantics, e.g. to implement a 3D array access a [ i ] [ j ] [ k ] = x ; , operator[] has to return a reference to a 2D plane, which has to have its own operator[] which returns a reference to a 1D row, which has to have operator[] which returns a reference to the element. To avoid this complexity, some libraries opt for overloading operator ( ) instead, so that 3D access expressions have the Fortran-like syntax a ( i, j, k ) = x ;
User-defined classes and enumerations that implement the requirements of BitmaskType are required to overload the bitwise arithmetic operators operator & , operator | , operator ^ , operator~ , operator & = , operator | = , and operator ^ = , and may optionally overload the shift operators operator << operator >> , operator >>= , and operator <<= . The canonical implementations usually follow the pattern for binary arithmetic operators described above.
The operator operator ! is commonly overloaded by the user-defined classes that are intended to be used in boolean contexts. Such classes also provide a user-defined conversion function explicit operator bool ( ) (see std::basic_ios for the standard library example), and the expected behavior of operator ! is to return the value opposite of operator bool .
The following operators are rarely overloaded:
The following behavior-changing defect reports were applied retroactively to previously published C++ standards.
DR | Applied to | Behavior as published | Correct behavior |
---|---|---|---|
C++11 | taking address of incomplete type that overloads address-of was undefined behavior | the behavior is only unspecified |
Common operators | ||||||
---|---|---|---|---|---|---|
a = b | ++a | +a | !a | a == b | a[b] | a(...) |
Special operators | ||||||
converts one type to another related type |
Find centralized, trusted content and collaborate around the technologies you use most.
Q&A for work
Connect and share knowledge within a single location that is structured and easy to search.
Get early access and see previews of new features.
error: passing 'const string {aka const std::__cxx11::basic_string<char>}' as 'this' argument discards qualifiers [-fpermissive]
I have a class like this and need to build a copy assignment operator where the name_ must be const .
How to overcome the error?
you can use the const casting like so
Reminder: Answers generated by artificial intelligence tools are not allowed on Stack Overflow. Learn more
Post as a guest.
Required, but never shown
By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy .
IMAGES
VIDEO
COMMENTS
Triviality of eligible copy assignment operators determines whether the class is a trivially copyable type. [] NoteIf both copy and move assignment operators are provided, overload resolution selects the move assignment if the argument is an rvalue (either a prvalue such as a nameless temporary or an xvalue such as the result of std::move), and selects the copy assignment if the argument is an ...
21.12 — Overloading the assignment operator. Alex July 22, 2024. The copy assignment operator (operator=) is used to copy values from one object to another already existing object. As of C++11, C++ also supports "Move assignment". We discuss move assignment in lesson 22.3 -- Move constructors and move assignment .
One thing to note is that if you aren't needing a deep copy it's sometimes considered best to use the implicit copy constructor and assignment operator generated by the compiler than roll your own. ... // Operator overloading in C++ //assignment operator overloading #include<iostream> using namespace std; class Employee { private: int idNum ...
C++ compiler implicitly provides a copy constructor, if no copy constructor is defined in the class. A bitwise copy gets created, if the Assignment operator is not overloaded. Consider the following C++ program. Explanation: Here, t2 = t1; calls the assignment operator, same as t2.operator= (t1); and Test t3 = t1; calls the copy constructor ...
The assignment operator,"=", is the operator used for Assignment. It copies the right value into the left value. Assignment Operators are predefined to operate only on built-in Data types. Assignment operator overloading is binary operator overloading. Overloading assignment operator in C++ copies all values of one object to another object.
Commonly overloaded operators have the following typical, canonical forms: Assignment operator. The assignment operator (operator =) has special properties: see copy assignment and move assignment for details. The canonical copy-assignment operator is expected to be safe on self-assignment, and to return the lhs by reference:
The copy assignment operator is called whenever selected by overload resolution, e.g. when an object appears on the left side of an assignment expression. Implicitly-declared copy assignment operator If no user-defined copy assignment operators are provided for a class type ( struct , class , or union ), the compiler will always declare one as ...
If both copy and move assignment operators are provided, overload resolution selects the move assignment if the argument is an rvalue (either prvalue such as a nameless temporary or xvalue such as the result of std::move), and selects the copy assignment if the argument is lvalue (named object or a function/operator returning lvalue reference ...
In the C++ programming language, the assignment operator, =, is the operator used for assignment. Like most other operators in C++, it can be overloaded . The copy assignment operator, often just called the "assignment operator", is a special case of assignment operator where the source (right-hand side) and destination (left-hand side) are of ...
remaining lines are assignment operators which can also throw. HOWEVER, if you have a type T for which the default std::swap() may result in either T's copy constructor or assignment operator throwing, you are politely required to provide a swap() overload for your type that does not throw.
Use an assignment operator operator= that returns a reference to the class type and takes one parameter that's passed by const reference—for example ClassName& operator=(const ClassName& x);. Use the copy constructor. If you don't declare a copy constructor, the compiler generates a member-wise copy constructor for you.
1) Do not allow assignment of one object to other object. We can create our own dummy assignment operator and make it private. 2) Write your own assignment operator that does deep copy. Same is true for Copy Constructor. Following is an example of overloading assignment operator for the above class. #include<iostream>.
The copy assignment operator is called whenever selected by overload resolution, e.g. when an object appears on the left side of an assignment expression. [] Implicitly-declared copy assignment operatoIf no user-defined copy assignment operators are provided for a class type (struct, class, or union), the compiler will always declare one as an inline public member of the class.
Shallow copying. Because C++ does not know much about your class, the default copy constructor and default assignment operators it provides use a copying method known as a memberwise copy (also known as a shallow copy).This means that C++ copies each member of the class individually (using the assignment operator for overloaded operator=, and direct initialization for the copy constructor).
walnut. 22.1k 4 28 64. If I understand your reasoning correctly, for the example that you have provided (a=b=c), it would be simplified as follows: 1) a = (b = c); // copy assignment called first time in which b is assigned with c and reference is being returned simplifying the expression to 2) a = (reference returned when operator was first ...
Overloading assignments (C++ only) You overload the assignment operator, operator=, with a nonstatic member function that has only one parameter. You cannot declare an overloaded assignment operator that is a nonmember function. The following example shows how you can overload the assignment operator for a particular class: struct X {. int data;
Triviality of eligible move assignment operators determines whether the class is a trivially copyable type. [] NoteIf both copy and move assignment operators are provided, overload resolution selects the move assignment if the argument is an rvalue (either a prvalue such as a nameless temporary or an xvalue such as the result of std::move), and selects the copy assignment if the argument is an ...
Commonly overloaded operators have the following typical, canonical forms: Assignment operator. The assignment operator (operator =) has special properties: see copy assignment and move assignment for details. The canonical copy-assignment operator is expected to perform no action on self-assignment, and to return the lhs by reference:
When a2 is initialised, a temporary copy of a1 is made and then the operator is evaluated with respect to the Base class, hence the Base overloaded copy assignment block is run, and the a1 object is returned via return *this to the reference a2.
layout: true <div class=bot-bar> Python </div> --- class: center, middle # Python #### `import tensorflow as tf` --- # Overview * High level scripting * What is ...
4. Correct me if I'm wrong: I understand that when having a class with members that are pointers, a copy of a class object will result in that the pointers representing the same memory address. This can result in changes done to one class object to affect all copies of this object. A solution to this can be to overload the = operator.
If you must supply an operator=() for a class with a const member you must (1) justify such a broken design (2) implement the operator=() so it assigns other members, but not the const ones. @TedLyngmo Presumably the copy constructor should copy name_, since its only other choice would be to make it empty. But if the class does that, it will ...