[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)
