[class.copy.assign] # 11 Classes [[class]](./#class) ## 11.4 Class members [[class.mem]](class.mem#class.copy.assign) ### 11.4.6 Copy/move assignment operator [class.copy.assign] [1](#1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L1787) A user-declared [*copy*](#def:copy) assignment operator X​::​operator= is a non-static non-template member function of class X with exactly one non-object parameter of type X, X&, const X&,volatile X&, or const volatile X&[.](#1.sentence-1)[90](#footnote-90 "Because a template assignment operator or an assignment operator taking an rvalue reference parameter is never a copy assignment operator, the presence of such an assignment operator does not suppress the implicit declaration of a copy assignment operator. Such assignment operators participate in overload resolution with other assignment operators, including copy assignment operators, and, if selected, will be used to assign an object.") [*Note [1](#note-1)*: More than one form of copy assignment operator can be declared for a class[.](#1.sentence-2) — *end note*] [*Note [2](#note-2)*: If a classX only has a copy assignment operator with a non-object parameter of typeX&, an expression of type constX cannot be assigned to an object of typeX[.](#1.sentence-3) [*Example [1](#example-1)*: struct X { X(); X& operator=(X&);};const X cx; X x;void f() { x = cx; // error: X​::​operator=(X&) cannot assign cx into x} — *end example*] — *end note*] [2](#2) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L1835) If the class definition does not explicitly declare a copy assignment operator, one is declared [*implicitly*](#def:assignment_operator,copy,implicitly_declared "11.4.6 Copy/move assignment operator [class.copy.assign]")[.](#2.sentence-1) If the class definition declares a move constructor or move assignment operator, the implicitly declared copy assignment operator is defined as deleted; otherwise, it is defaulted ([[dcl.fct.def]](dcl.fct.def "9.6 Function definitions"))[.](#2.sentence-2) The latter case is deprecated if the class has a user-declared copy constructor or a user-declared destructor ([[depr.impldec]](depr.impldec "D.6 Implicit declaration of copy functions"))[.](#2.sentence-3) The implicitly-declared copy assignment operator for a classX will have the formX& X::operator=(const X&) if - [(2.1)](#2.1) each direct base class B of X has a copy assignment operator whose non-object parameter is of typeconst B&, const volatile B&, or B, and - [(2.2)](#2.2) for all the non-static data members of X that are of a class type M (or array thereof), each such class type has a copy assignment operator whose non-object parameter is of typeconst M&, const volatile M&, or M[.](#2.sentence-4)[91](#footnote-91 "This implies that the reference parameter of the implicitly-declared copy assignment operator cannot bind to a volatile lvalue; see [diff.class].") Otherwise, the implicitly-declared copy assignment operator will have the formX& X::operator=(X&) [3](#3) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L1875) A user-declared move assignment operator X​::​operator= is a non-static non-template member function of class X with exactly one non-object parameter of type X&&, const X&&, volatile X&&, orconst volatile X&&[.](#3.sentence-1) [*Note [3](#note-3)*: More than one form of move assignment operator can be declared for a class[.](#3.sentence-2) — *end note*] [4](#4) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L1884) If the definition of a class X does not explicitly declare a move assignment operator, one will be implicitly declared as defaulted if and only if - [(4.1)](#4.1) X does not have a user-declared copy constructor, - [(4.2)](#4.2) X does not have a user-declared move constructor, - [(4.3)](#4.3) X does not have a user-declared copy assignment operator, and - [(4.4)](#4.4) X does not have a user-declared destructor[.](#4.sentence-1) [*Example [2](#example-2)*: The class definitionstruct S {int a; S& operator=(const S&) = default;}; will not have a default move assignment operator implicitly declared because the copy assignment operator has been user-declared[.](#4.sentence-2) The move assignment operator may be explicitly defaulted[.](#4.sentence-3) struct S {int a; S& operator=(const S&) = default; S& operator=(S&&) = default;}; — *end example*] [5](#5) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L1924) The implicitly-declared move assignment operator for a class X will have the formX& X::operator=(X&&) [6](#6) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L1930) The implicitly-declared copy/move assignment operator for classX has the return typeX&[.](#6.sentence-1) An implicitly-declared copy/move assignment operator is an inline public member of its class[.](#6.sentence-2) [7](#7) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L1938) A defaulted copy/move assignment operator for class X is defined as deleted if X has: - [(7.1)](#7.1) a non-static data member of const non-class type (or possibly multidimensional array thereof), or - [(7.2)](#7.2) a non-static data member of reference type, or - [(7.3)](#7.3) a direct non-static data member of class type M (or possibly multidimensional array thereof) or a direct base class M that cannot be copied/moved because overload resolution ([[over.match]](over.match "12.2 Overload resolution")), as applied to find M's corresponding assignment operator, either does not result in a usable candidate ([[over.match.general]](over.match.general "12.2.1 General")) or, in the case of a variant member, selects a non-trivial function[.](#7.sentence-1) [*Note [4](#note-4)*: A defaulted move assignment operator that is defined as deleted is ignored by overload resolution ([[over.match]](over.match "12.2 Overload resolution"), [[over.over]](over.over "12.3 Address of an overload set"))[.](#7.sentence-2) — *end note*] [8](#8) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L1961) Because a copy/move assignment operator is implicitly declared for a class if not declared by the user, a base class copy/move assignment operator is always hidden by the corresponding assignment operator of a derived class ([[over.assign]](over.assign "12.4.3.2 Simple assignment"))[.](#8.sentence-1) [*Note [5](#note-5)*: A [*using-declaration*](namespace.udecl#nt:using-declaration "9.10 The using declaration [namespace.udecl]") in a derived class C that names an assignment operator from a base class never suppresses the implicit declaration of an assignment operator of C, even if the base class assignment operator would be a copy or move assignment operator if declared as a member of C[.](#8.sentence-2) — *end note*] [9](#9) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L1978) A copy/move assignment operator for classX is trivial if it is not user-provided and if - [(9.1)](#9.1) classX has no virtual functions ([[class.virtual]](class.virtual "11.7.3 Virtual functions")) and no virtual base classes ([[class.mi]](class.mi "11.7.2 Multiple base classes")), and - [(9.2)](#9.2) the assignment operator selected to copy/move each direct base class subobject is trivial, and - [(9.3)](#9.3) for each non-static data member ofX that is of class type (or array thereof), the assignment operator selected to copy/move that member is trivial; otherwise the copy/move assignment operator is[*non-trivial*](#def:assignment_operator,copy,non-trivial "11.4.6 Copy/move assignment operator [class.copy.assign]")[.](#9.sentence-1) [10](#10) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L2006) An implicitly-defined ([[dcl.fct.def.default]](dcl.fct.def.default "9.6.2 Explicitly-defaulted functions")) copy/move assignment operator is constexpr[.](#10.sentence-1) [11](#11) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L2009) Before the defaulted copy/move assignment operator for a class is implicitly defined, all non-user-provided copy/move assignment operators for its direct base classes and its non-static data members are implicitly defined[.](#11.sentence-1) [*Note [6](#note-6)*: An implicitly-declared copy/move assignment operator has an implied exception specification ([[except.spec]](except.spec "14.5 Exception specifications"))[.](#11.sentence-2) — *end note*] [12](#12) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L2020) The implicitly-defined copy/move assignment operator for a non-union class X performs memberwise copy/move assignment of its subobjects[.](#12.sentence-1) The direct base classes of X are assigned first, in the order of their declaration in the[*base-specifier-list*](class.derived.general#nt:base-specifier-list "11.7.1 General [class.derived.general]"), and then the immediate non-static data members ofX are assigned, in the order in which they were declared in the class definition[.](#12.sentence-2) Let x be either the parameter of the function or, for the move operator, an xvalue referring to the parameter[.](#12.sentence-3) Each subobject is assigned in the manner appropriate to its type: - [(12.1)](#12.1) if the subobject is of class type, as if by a call to operator= with the subobject as the object expression and the corresponding subobject of x as a single function argument (as if by explicit qualification; that is, ignoring any possible virtual overriding functions in more derived classes); - [(12.2)](#12.2) if the subobject is an array, each element is assigned, in the manner appropriate to the element type; - [(12.3)](#12.3) if the subobject is of scalar type, the built-in assignment operator is used[.](#12.sentence-4) It is unspecified whether subobjects representing virtual base classes are assigned more than once by the implicitly-defined copy/move assignment operator[.](#12.sentence-5) [*Example [3](#example-3)*: struct V { };struct A : virtual V { };struct B : virtual V { };struct C : B, A { }; It is unspecified whether the virtual base class subobjectV is assigned twice by the implicitly-defined copy/move assignment operator forC[.](#12.sentence-6) — *end example*] [13](#13) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L2063) The implicitly-defined copy/move assignment operator for a union X copies the object representation ([[basic.types.general]](basic.types.general#term.object.representation "6.9.1 General")) of X[.](#13.sentence-1) If the source and destination of the assignment are not the same object, then for each object nested within ([[intro.object]](intro.object "6.8.2 Object model")) the object that is the source of the copy, a corresponding object o nested within the destination is created, and the lifetime of o begins before the copy is performed[.](#13.sentence-2) [14](#14) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/classes.tex#L2072) The implicitly-defined copy/move assignment operator for a class returns the object for which the assignment operator is invoked, that is, the object assigned to[.](#14.sentence-1) [90)](#footnote-90)[90)](#footnoteref-90) Because a template assignment operator or an assignment operator taking an rvalue reference parameter is never a copy assignment operator, the presence of such an assignment operator does not suppress the implicit declaration of a copy assignment operator[.](#footnote-90.sentence-1) Such assignment operators participate in overload resolution with other assignment operators, including copy assignment operators, and, if selected, will be used to assign an object[.](#footnote-90.sentence-2) [91)](#footnote-91)[91)](#footnoteref-91) This implies that the reference parameter of the implicitly-declared copy assignment operator cannot bind to avolatile lvalue; see [[diff.class]](diff.class "C.7.7 [class]: classes")[.](#footnote-91.sentence-1)