Copy assignment operator

A copy assignment operator of class T is a non-template non-static member function with the name operator = that takes exactly one parameter of type T , T & , const T & , volatile T & , or const volatile T & . A type with a public copy assignment operator is CopyAssignable .

[ edit ] Syntax

[ edit ] explanation.

  • Typical declaration of a copy assignment operator when copy-and-swap idiom can be used
  • Typical declaration of a copy assignment operator when copy-and-swap idiom cannot be used
  • Forcing a copy assignment operator to be generated by the compiler
  • Avoiding implicit copy assignment

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.

[ edit ] 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 an inline public member of the class. This implicitly-declared copy assignment operator has the form T & T :: operator = ( const T & ) if all of the following is true:

  • each direct base B of T has a copy assignment operator whose parameters are B or const B& or const volatile B &
  • each non-static data member M of T of class type or array of class type has a copy assignment operator whose parameters are M or const M& or const volatile M &

Otherwise the implicitly-declared copy assignment operator is declared as T & T :: operator = ( T & ) . (Note that due to these rules, the implicitly-declared copy assignment operator cannot bind to a volatile lvalue argument)

A class can have multiple copy assignment operators, e.g. both T & T :: operator = ( const T & ) and T & T :: operator = ( T ) . If some user-defined copy assignment operators are present, the user may still force the generation of the implicitly declared copy assignment operator with the keyword default .

Because the copy assignment operator is always declared for any class, the base class assignment operator is always hidden. If a using-declaration is used to bring in the assignment operator from the base class, and its argument type could be the same as the argument type of the implicit assignment operator of the derived class, the using-declaration is also hidden by the implicit declaration.

[ edit ] Deleted implicitly-declared copy assignment operator

The implicitly-declared or defaulted copy assignment operator for class T is defined as deleted in any of the following is true:

  • T has a non-static data member that is const
  • T has a non-static data member of a reference type.
  • T has a non-static data member that cannot be copy-assigned (has deleted, inaccessible, or ambiguous copy assignment operator)
  • T has direct or virtual base class that cannot be copy-assigned (has deleted, inaccessible, or ambiguous move assignment operator)
  • T has a user-declared move constructor
  • T has a user-declared move assignment operator

[ edit ] Trivial copy assignment operator

The implicitly-declared copy assignment operator for class T is trivial if all of the following is true:

  • T has no virtual member functions
  • T has no virtual base classes
  • The copy assignment operator selected for every direct base of T is trivial
  • The copy assignment operator selected for every non-static class type (or array of class type) memeber of T is trivial

A trivial copy assignment operator makes a copy of the object representation as if by std:: memmove . All data types compatible with the C language (POD types) are trivially copy-assignable.

[ edit ] Implicitly-defined copy assignment operator

If the implicitly-declared copy assignment operator is not deleted or trivial, it is defined (that is, a function body is generated and compiled) by the compiler. 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, using built-in assignment for the scalars and copy assignment operator for class types.

The generation of the implicitly-defined copy assignment operator is deprecated (since C++11) if T has a user-declared destructor or user-declared copy constructor.

[ edit ] Notes

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

[ edit ] Copy and swap

Copy assignment operator can be expressed in terms of copy constructor, destructor, and the swap() member function, if one is provided:

T & T :: operator = ( T arg ) { // copy/move constructor is called to construct arg     swap ( arg ) ;     // resources exchanged between *this and arg     return * this ; }   // destructor is called to release the resources formerly held by *this

For non-throwing swap(), this form provides strong exception guarantee . For rvalue arguments, this form automatically invokes the move constructor, and is sometimes referred to as "unifying assignment operator" (as in, both copy and move).

[ edit ] Example

Copy assignment operator

A copy assignment operator of class T is a non-template non-static member function with the name operator= that takes exactly one parameter (that isn't an explicit object parameter ) of type T , T& , const T& , volatile T& , or const volatile T& . For a type to be CopyAssignable , it must have a public copy assignment operator.

Explanation

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 an inline public member of the class. This implicitly-declared copy assignment operator has the form T& T::operator=(const T&) if all of the following is true:

  • each direct base B of T has a copy assignment operator whose parameters are B or const B& or const volatile B& ;
  • each non-static data member M of T of class type or array of class type has a copy assignment operator whose parameters are M or const M& or const volatile M& .

Otherwise the implicitly-declared copy assignment operator is declared as T& T::operator=(T&) . (Note that due to these rules, the implicitly-declared copy assignment operator cannot bind to a volatile lvalue argument.).

A class can have multiple copy assignment operators, e.g. both T& T::operator=(T&) and T& T::operator=(T) . If some user-defined copy assignment operators are present, the user may still force the generation of the implicitly declared copy assignment operator with the keyword default . (since C++11) .

The implicitly-declared (or defaulted on its first declaration) copy assignment operator has an exception specification as described in dynamic exception specification (until C++17) noexcept specification (since C++17) .

Because the copy assignment operator is always declared for any class, the base class assignment operator is always hidden. If a using-declaration is used to bring in the assignment operator from the base class, and its argument type could be the same as the argument type of the implicit assignment operator of the derived class, the using-declaration is also hidden by the implicit declaration.

Deleted implicitly-declared copy assignment operator

An implicitly-declared copy assignment operator for class T is defined as deleted if any of the following is true:

  • T has a user-declared move constructor;
  • T has a user-declared move assignment operator.

Otherwise, it is defined as defaulted.

A defaulted copy assignment operator for class T is defined as deleted if any of the following is true:

  • T has a non-static data member of a const-qualified non-class type (or array thereof);
  • T has a non-static data member of a reference type;
  • T has a non-static data member or a direct base class that cannot be copy-assigned (overload resolution for the copy assignment fails, or selects a deleted or inaccessible function);
  • T is a union-like class , and has a variant member whose corresponding assignment operator is non-trivial.

Trivial copy assignment operator

The copy assignment operator for class T is trivial if all of the following is true:

  • it is not user-provided (meaning, it is implicitly-defined or defaulted);
  • T has no virtual member functions;
  • T has no virtual base classes;
  • the copy assignment operator selected for every direct base of T is trivial;
  • the copy assignment operator selected for every non-static class type (or array of class type) member of T is trivial.

A trivial copy assignment operator makes a copy of the object representation as if by std::memmove . All data types compatible with the C language (POD types) are trivially copy-assignable.

Eligible copy assignment operator

Triviality of eligible copy assignment operators determines whether the class is a trivially copyable type .

Implicitly-defined copy assignment operator

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.

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.

Defect reports

The following behavior-changing defect reports were applied retroactively to previously published C++ standards.

  • converting constructor
  • copy constructor
  • copy elision
  • default constructor
  • aggregate initialization
  • constant initialization
  • copy initialization
  • default initialization
  • direct initialization
  • initializer list
  • list initialization
  • reference initialization
  • value initialization
  • zero initialization
  • move assignment
  • move constructor

© cppreference.com Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0. https://en.cppreference.com/w/cpp/language/as_operator

  • Windows Programming
  • UNIX/Linux Programming
  • General C++ Programming
  • Assignment operator implicitly deleted

  Assignment operator implicitly deleted

c copy assignment operator is implicitly deleted

This browser is no longer supported.

Upgrade to Microsoft Edge to take advantage of the latest features, security updates, and technical support.

Explicitly Defaulted and Deleted Functions

  • 8 contributors

In C++11, defaulted and deleted functions give you explicit control over whether the special member functions are automatically generated. Deleted functions also give you simple language to prevent problematic type promotions from occurring in arguments to functions of all types—special member functions, and normal member functions and nonmember functions—which would otherwise cause an unwanted function call.

Benefits of explicitly defaulted and deleted functions

In C++, the compiler automatically generates the default constructor, copy constructor, copy-assignment operator, and destructor for a type if it doesn't declare its own. These functions are known as the special member functions , and they're what make simple user-defined types in C++ behave like structures do in C. That is, you can create, copy, and destroy them without extra coding effort. C++11 brings move semantics to the language and adds the move constructor and move-assignment operator to the list of special member functions that the compiler can automatically generate.

This is convenient for simple types, but complex types often define one or more of the special member functions themselves, and this can prevent other special member functions from being automatically generated. In practice:

If any constructor is explicitly declared, then no default constructor is automatically generated.

If a virtual destructor is explicitly declared, then no default destructor is automatically generated.

If a move constructor or move-assignment operator is explicitly declared, then:

No copy constructor is automatically generated.

No copy-assignment operator is automatically generated.

If a copy constructor, copy-assignment operator, move constructor, move-assignment operator, or destructor is explicitly declared, then:

No move constructor is automatically generated.

No move-assignment operator is automatically generated.

Additionally, the C++11 standard specifies the following additional rules:

  • If a copy constructor or destructor is explicitly declared, then automatic generation of the copy-assignment operator is deprecated.
  • If a copy-assignment operator or destructor is explicitly declared, then automatic generation of the copy constructor is deprecated.

In both cases, Visual Studio continues to automatically generate the necessary functions implicitly, and doesn't emit a warning by default. Since Visual Studio 2022 version 17.7, C5267 can be enabled to emit a warning.

The consequences of these rules can also leak into object hierarchies. For example, if for any reason a base class fails to have a default constructor that's callable from a deriving class—that is, a public or protected constructor that takes no parameters—then a class that derives from it can't automatically generate its own default constructor.

These rules can complicate the implementation of what should be straight-forward, user-defined types and common C++ idioms—for example, making a user-defined type noncopyable by declaring the copy constructor and copy-assignment operator privately and not defining them.

Before C++11, this code snippet was the idiomatic form of noncopyable types. However, it has several problems:

The copy constructor has to be declared privately to hide it, but because it's declared at all, automatic generation of the default constructor is prevented. You have to explicitly define the default constructor if you want one, even if it does nothing.

Even if the explicitly defined default constructor does nothing, the compiler considers it to be nontrivial. It's less efficient than an automatically generated default constructor and prevents noncopyable from being a true POD type.

Even though the copy constructor and copy-assignment operator are hidden from outside code, the member functions and friends of noncopyable can still see and call them. If they're declared but not defined, calling them causes a linker error.

Although this is a commonly accepted idiom, the intent isn't clear unless you understand all of the rules for automatic generation of the special member functions.

In C++11, the noncopyable idiom can be implemented in a way that is more straightforward.

Notice how the problems with the pre-C++11 idiom are resolved:

Generation of the default constructor is still prevented by declaring the copy constructor, but you can bring it back by explicitly defaulting it.

Explicitly defaulted special member functions are still considered trivial, so there's no performance penalty, and noncopyable isn't prevented from being a true POD type.

The copy constructor and copy-assignment operator are public but deleted. It's a compile-time error to define or call a deleted function.

The intent is clear to anyone who understands =default and =delete . You don't have to understand the rules for automatic generation of special member functions.

Similar idioms exist for making user-defined types that are nonmovable, that can only be dynamically allocated, or that can't be dynamically allocated. Each of these idioms have pre-C++11 implementations that suffer similar problems, and that are similarly resolved in C++11 by implementing them in terms of defaulted and deleted special member functions.

Explicitly defaulted functions

You can default any of the special member functions—to explicitly state that the special member function uses the default implementation, to define the special member function with a nonpublic access qualifier, or to reinstate a special member function whose automatic generation was prevented by other circumstances.

You default a special member function by declaring it as in this example:

Notice that you can default a special member function outside the body of a class as long as it's inlinable.

Because of the performance benefits of trivial special member functions, we recommend that you prefer automatically generated special member functions over empty function bodies when you want the default behavior. You can do this either by explicitly defaulting the special member function, or by not declaring it (and also not declaring other special member functions that would prevent it from being automatically generated.)

Deleted functions

You can delete special member functions and normal member functions and nonmember functions to prevent them from being defined or called. Deleting of special member functions provides a cleaner way of preventing the compiler from generating special member functions that you don't want. The function must be deleted as it's declared; it can't be deleted afterwards in the way that a function can be declared and then later defaulted.

Deleting of normal member function or nonmember functions prevents problematic type promotions from causing an unintended function to be called. This works because deleted functions still participate in overload resolution and provide a better match than the function that could be called after the types are promoted. The function call resolves to the more-specific—but deleted—function and causes a compiler error.

Notice in the preceding sample that calling call_with_true_double_only by using a float argument would cause a compiler error, but calling call_with_true_double_only by using an int argument wouldn't; in the int case, the argument will be promoted from int to double and successfully call the double version of the function, even though that might not be what you intend. To ensure that any call to this function by using a non-double argument causes a compiler error, you can declare a template version of the deleted function.

Was this page helpful?

Coming soon: Throughout 2024 we will be phasing out GitHub Issues as the feedback mechanism for content and replacing it with a new feedback system. For more information see: https://aka.ms/ContentUserFeedback .

Submit and view feedback for

Additional resources

Fluent C++

About Jonathan Boccara

Hello, my name is Jonathan Boccara, I'm your host on Fluent C++. I have been a developer for 10 years. My focus is on how to write expressive code . I wrote the book The Legacy Code Programmer's Toolbox . I'm happy to take your feedback, don't hesitate to drop a comment on a post, follow me or get in touch directly !

Jonathan Boccara's blog

Recent Posts

  • Usage First, Implementation After: A Principle of Software Development
  • Design Patterns VS Design Principles: Factory method
  • How to Store an lvalue or an rvalue in the Same Object
  • Copy-Paste Developments
  • Design Patterns VS Design Principles: Abstract Factory
  • How to Generate All the Combinations from Several Collections

c copy assignment operator is implicitly deleted

How to Make a Copyable Object Assignable in C++

Some types in C++ have a copy constructor that doesn’t have the same semantics as their assignment operator ( operator= ).

Take references, for example. References can be copied:

But it doesn’t do the same thing as assigning to them:

With the copy, r2 points to the same thing as r1 , but with the assignment r2 still points to the same object it was pointing to before.

Or take the example of copying a lambda:

The above code compiles fine.

Now if we add the following line:

It doesn’t compile. As the compiler (clang) says:

Lambdas don’t even have an operator= to begin with (except in C++20 where they do if they don’t capture anything).

Right. But is any of this a problem?

Why we need operator=

After all, the behaviour of the references makes some sense, and why on earth would we like to assign on a lambda we’ve just created?

However, there is a case when the absence of operator= becomes a problem: when the object that doesn’t have an operator= is a member of a class. It makes it difficult for that class to have an operator= itself. For one thing, the compiler is not going to write it for you.

Even for references, the compiler won’t generate an operator= for a class if one of its members is a reference. It assumes that you’d better write it yourself to choose what to do with the reference member.

This problem came up in a project I’ve been working on, the pipes library . This library has classes that have lambdas as data members, and passes objects of those classes as output iterators of STL algorithms. And in Visual Studio, the STL in debug mode calls the operator= on output iterators in the _Recheck function. So the class that contains a lambda needs an operator= .

Haven’t you ever faced too the situation where the compiler couldn’t write the operator= you needed because of a problematic data member?

The standard has us covered for references

In C++11, and equivalently in Boost long before that, std::reference_wrapper<T>  has the same behaviour as a reference (you initialize it with a reference, and it even has a operator T& ) with one exception: it has an operator= that rebinds the reference.

This means that after calling operator= between two std::reference_wrapper s, they point to the same object:

The fact that std::reference_wrapper<T> has an operator= allows the compiler to generate an operator= for the classes that contains it. And the fact that it rebinds gives the operator= of the containing class a natural behaviour.

Why is this behaviour natural? Because it is consistent with the copy of the reference: in both case, the two reference(_wrapper)s point to the same object after the operation.

The general case

Even if the case of references is solved with std::reference_wrapper , the case of the lambda remains unsolved, along with all the types that have a copy constructor and no operator= .

Let’s design a component, inspired from std::reference_wrapper , that would add to any type an operator= which is consistent with its copy constructor.

If you have an idea on how to name this component, just leave a comment below at the bottom of the post. For the time being, let’s call it assignable .

assignable needs an operator= that relies on the copy constructor of its underlying type. Fortunately, we know how to implement that with a std::optional , like we saw in How to Implement operator= When a Data Member Is a Lambda :

But now that we’ve written the copy assignment operator, the compiler is going to refrain from generating the move constructor and the move assignment operator. It’s a shame, so let’s add them back:

Now that we’ve written all this, we might as well write the copy constructor too. The compiler would have generated it for us, but I think it looks odd to write everything except this one:

Finally, in order to hide from its users the fact that assignable contains an optional , let’s add constructors that accepts a T :

Giving access to the underlying value

Like optional , assignable wraps a type to add an extra feature, but its goal is not to mimic the interface of the underlying object. So we should give access to the underlying object of assignable . We will define a get()  member function, because  operator*  and operator->  could suggest that there is an indirection (like for pointers and iterators).

The underlying object of the  assignable happens to to be the underlying object of the optional inside of the assignable :

We don’t check for the nullity of the optional, because the interface of assignable is such that all the paths leading to those dereferencing operators guarantee that the optional has been initialized.

Which gives us food for thought: optional is not the optimal solution here. It contains a piece of information that we never use: whether the optional is null or not.

A better solution would be to create a component that does placement news like optional, but without the possibility to be null.

Lets keep this as food for thought for the moment. Maybe we’ll come back to it in a later article. Please leave a comment if you have thoughts on that.

Making the assignable callable

std::reference_wrapper has a little known feature that we explored in How to Pass a Polymorphic Object to an STL Algorithm : it has an operator() that calls its underlying reference when it’s callable.

This is all the more relevant for assignable since our motivating case was a lambda.

If we don’t implement operator() , we’d have to write code like this:

Whereas with an operator() , calling code becomes more natural, resembling the one of a lambda:

Let’s do it then!

We rely on C++14 decltype(auto) . Note that we could also implement this in C++11 the following way:

The case of assignable references

Now we have implemented an assignable<T> that works when T is a lambda.

But what if T is a reference?

It can happen in the case of a function reference. In that case, we need exactly the same features as the ones we needed with the lambda.

However, assignable<T> doesn’t even compile when T is a reference. Why? Because it uses an std::optional<T> and optional references didn’t make it in the C++ standard .

Luckily, implementing assignable for references is not difficult. In fact, it’s a problem already solved by… std::reference_wrapper !

So we need to create a specialization of assignable<T> when T is a reference. It would be great if we could just write this:

But this is not possible in C++.

Instead we have to implement a type that wraps std::reference_wrapper and relies on its behaviour:

This way, we can use assignable on reference types.

Putting it all together

In summary, here is all the code of assignable all put together:

And classes can use it as a data member this way:

For such as class, the compiler would be able to generate a operator= as long as Function has a copy constructor, which many classes–including lambdas–do.

Thanks to Eric Niebler for the inspiration, as assignable was inspired from techniques I’ve seen in range-v3 , which is my go-to model for library implementation.

If you have any piece of feedback on assignable , I’d love to hear it in a comment below!

You will also like

  • How to Pass a Polymorphic Object to an STL Algorithm
  • How to Implement operator= When a Data Member Is a Lambda
  • An Alternative Design to Iterators and Ranges, Using std::optional
  • Why Optional References Didn’t Make It In C++17
  • Pointers, References and Optional References in C++
  • Smart Output Iterators: A Symmetrical Approach to Range Adaptors

twitter

Copy assignment operator

A copy assignment operator of class T is a non-template non-static member function with the name operator = that takes exactly one parameter of type T , T & , const T & , volatile T & , or const volatile T & . For a type to be CopyAssignable , it must have a public copy assignment operator.

Explanation

  • Typical declaration of a copy assignment operator when copy-and-swap idiom can be used.
  • Typical declaration of a copy assignment operator when copy-and-swap idiom cannot be used (non-swappable type or degraded performance).
  • Forcing a copy assignment operator to be generated by the compiler.
  • Avoiding implicit copy assignment.

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 an inline public member of the class. This implicitly-declared copy assignment operator has the form T & T :: operator = ( const T & ) if all of the following is true:

  • each direct base B of T has a copy assignment operator whose parameters are B or const B & or const volatile B & ;
  • each non-static data member M of T of class type or array of class type has a copy assignment operator whose parameters are M or const M & or const volatile M & .

Otherwise the implicitly-declared copy assignment operator is declared as T & T :: operator = ( T & ) . (Note that due to these rules, the implicitly-declared copy assignment operator cannot bind to a volatile lvalue argument.)

A class can have multiple copy assignment operators, e.g. both T & T :: operator = ( const T & ) and T & T :: operator = ( T ) . If some user-defined copy assignment operators are present, the user may still force the generation of the implicitly declared copy assignment operator with the keyword default . (since C++11)

The implicitly-declared (or defaulted on its first declaration) copy assignment operator has an exception specification as described in dynamic exception specification (until C++17) exception specification (since C++17)

Because the copy assignment operator is always declared for any class, the base class assignment operator is always hidden. If a using-declaration is used to bring in the assignment operator from the base class, and its argument type could be the same as the argument type of the implicit assignment operator of the derived class, the using-declaration is also hidden by the implicit declaration.

Deleted implicitly-declared copy assignment operator

A implicitly-declared copy assignment operator for class T is defined as deleted if any of the following is true:

  • T has a user-declared move constructor;
  • T has a user-declared move assignment operator.

Otherwise, it is defined as defaulted.

A defaulted copy assignment operator for class T is defined as deleted if any of the following is true:

  • T has a non-static data member of non-class type (or array thereof) that is const ;
  • T has a non-static data member of a reference type;
  • T has a non-static data member or a direct or virtual base class that cannot be copy-assigned (overload resolution for the copy assignment fails, or selects a deleted or inaccessible function);
  • T is a union-like class , and has a variant member whose corresponding assignment operator is non-trivial.

Trivial copy assignment operator

The copy assignment operator for class T is trivial if all of the following is true:

  • it is not user-provided (meaning, it is implicitly-defined or defaulted) , , and if it is defaulted, its signature is the same as implicitly-defined (until C++14) ;
  • T has no virtual member functions;
  • T has no virtual base classes;
  • the copy assignment operator selected for every direct base of T is trivial;
  • the copy assignment operator selected for every non-static class type (or array of class type) member of T is trivial;

A trivial copy assignment operator makes a copy of the object representation as if by std::memmove . All data types compatible with the C language (POD types) are trivially copy-assignable.

Implicitly-defined copy assignment operator

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 . 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 generation of the implicitly-defined copy assignment operator is deprecated (since C++11) if T has a user-declared destructor or user-declared copy constructor.

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.

Defect reports

The following behavior-changing defect reports were applied retroactively to previously published C++ standards.

Copy assignment operators (C++ only)

The copy assignment operator lets you create a new object from an existing one by initialization. A copy assignment operator of a class A is a nonstatic non-template member function that has one of the following forms:

  • A::operator=(A)
  • A::operator=(A&)
  • A::operator=(const A&)
  • A::operator=(volatile A&)
  • A::operator=(const volatile A&)

If you do not declare a copy assignment operator for a class A , the compiler will implicitly declare one for you that is inline public.

The assignment x = y calls the implicitly defined copy assignment operator of B , which calls the user-defined copy assignment operator A::operator=(const A&) . The assignment w = z calls the user-defined operator A::operator=(A&) . The compiler will not allow the assignment i = j because an operator C::operator=(const C&) has not been defined.

The implicitly declared copy assignment operator of a class A will have the form A& A::operator=(const A&) if the following statements are true:

  • A direct or virtual base B of class A has a copy assignment operator whose parameter is of type const B& , const volatile B& , or B .
  • A non-static class type data member of type X that belongs to class A has a copy constructor whose parameter is of type const X& , const volatile X& , or X .

If the above are not true for a class A , the compiler will implicitly declare a copy assignment operator with the form A& A::operator=(A&) .

The implicitly declared copy assignment operator returns an lvalue reference to the operator's argument.

The copy assignment operator of a derived class hides the copy assignment operator of its base class.

  • Class A has a nonstatic data member of a const type or a reference type
  • Class A has a nonstatic data member of a type which has an inaccessible copy assignment operator
  • Class A is derived from a base class with an inaccessible copy assignment operator.

An implicitly defined copy assignment operator of a class A will first assign the direct base classes of A in the order that they appear in the definition of A . Next, the implicitly defined copy assignment operator will assign the nonstatic data members of A in the order of their declaration in the definition of A .

IMAGES

  1. C++ : Why do reference type members cause implicitly-declared copy

    c copy assignment operator is implicitly deleted

  2. What Is Deleted Implicitly-declared Copy Assignment Operator In C++

    c copy assignment operator is implicitly deleted

  3. C++ : Call to implicitly deleted copy constructor in LLVM

    c copy assignment operator is implicitly deleted

  4. 2 Wrong Way to Learn Copy Assignment Operator in C++ With Example

    c copy assignment operator is implicitly deleted

  5. C# Assignment Operator

    c copy assignment operator is implicitly deleted

  6. Error: Call to Implicitly-Deleted Copy Constructor of std::unique_ptr

    c copy assignment operator is implicitly deleted

VIDEO

  1. Implicitly Meaning

  2. Assignment Operator in C Programming

  3. Assignment Operator in C Programming

  4. Diane Archer on Medicare Advantage. A Canadian-American returns to Canada for healthcare. (#PTFB)

  5. 如何用讀寫鎖實作 thread safe copy constructor and copy assignment?

  6. Augmented assignment operators in C

COMMENTS

  1. C++

    Why this fails: If either element in the pair is const, the assignment operator for that element is itself deleted. You couldn't assign to a const string but that's exactly what you're asking it to do when you assign to pair<const string, T>. To simplify the example. std::pair<const int, int> p(0, 0);

  2. Copy assignment operator

    Deleted copy assignment operator. An implicitly-declared or explicitly-defaulted (since C++11) copy assignment operator for class T is undefined (until C++11) defined as deleted (since C++11) if any of the following conditions is satisfied: T has a non-static data member of a const-qualified non-class type (or possibly multi-dimensional array ...

  3. c++

    Closed 4 years ago. I'm trying to make a move operator for a class (which we will call A) that contains another reference to another class (which we will call B ), whose copy constructor has been implicitly deleted because it contains another reference. A simple example has been shown below. public: int & num; B(int & _num) : num(_num) {} public:

  4. Copy assignment operator

    Implicitly-defined copy assignment operator. 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. For union types, the implicitly-defined copy assignment copies the object representation (as by std::memmove).

  5. Copy assignment operator

    Implicitly-defined copy assignment operator. If the implicitly-declared copy assignment operator is not deleted or trivial, it is defined (that is, a function body is generated and compiled) by the compiler. For union types, the implicitly-defined copy assignment copies the object representation (as by std:: memmove).

  6. Copy Assignment Operator

    Triviality of eligible copy assignment operators determines whether the class is a trivially copyable type.. Implicitly-defined copy assignment operator. 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).

  7. Compiler warning C5267

    If the class definition declares a move constructor or move assignment operator, the implicitly declared copy constructor is defined as deleted; otherwise, it is defaulted. The latter case is deprecated if the class has a user-declared copy assignment operator or a user-declared destructor." Annex D D.8, which says: "The implicit definition of ...

  8. c++

    Deleted implicitly-declared copy assignment operator The implicitly-declared or defaulted copy assignment operator for class T is defined as deleted in any of the following is true: T has a non-static data member that is const T has a non-static data member of a reference type.

  9. Assignment operator implicitly deleted

    Deleted implicitly-declared copy assignment operator. A implicitly-declared copy assignment operator for class T is defined as deleted if any of the following is true: • T has a user-declared move constructor; • T has a user-declared move assignment operator. Otherwise, it is defined as defaulted.

  10. Explicitly Defaulted and Deleted Functions

    Benefits of explicitly defaulted and deleted functions. In C++, the compiler automatically generates the default constructor, copy constructor, copy-assignment operator, and destructor for a type if it doesn't declare its own. These functions are known as the special member functions, and they're what make simple user-defined types in C++ ...

  11. Copy assignment operator

    Implicitly-defined copy assignment operator. If the implicitly-declared copy assignment operator is not deleted or trivial, it is defined (that is, a function body is generated and compiled) by the compiler. For union types, the implicitly-defined copy assignment copies the object representation (as by std::memmove).

  12. Everything You Need To Know About The Copy Assignment Operator In C++

    The Copy Assignment Operator in a class is a non-template non-static member function that is declared with the operator=. When you create a class or a type that is copy assignable (that you can copy with the = operator symbol), it must have a public copy assignment operator. Here is a simple syntax for the typical declaration of a copy ...

  13. Copy constructors

    The implicitly-declared (or defaulted on its first declaration) copy constructor has an exception specification as described in dynamic exception specification (until C++17) noexcept specification (since C++17). [] Implicitly-defined copy constructoIf the implicitly-declared copy constructor is not deleted, it is defined (that is, a function body is generated and compiled) by the compiler if ...

  14. What Is Deleted Implicitly-declared Copy Assignment Operator In C++?

    In the C++ programming language, Object-Oriented Programming (OOP) is a good way to represent and manipulate data and work with functions.Classes and Objects are the best way to work on properties and methods. In a professional C++ Compiler, one of the OOP features is the copy assignment operator that is used with "operator=" to create a new object from an existing one.

  15. c++

    7. According to the C++ reference on Copy assignment operator: A defaulted copy assignment operator for class T is defined as deleted if any of the following is true. T has a non-static data member of non-class type (or array thereof) that is const ... I was hoping to create a case where I had a const class-type data member and a defaulted copy ...

  16. How to Make a Copyable Object Assignable in C++

    Some types in C++ have a copy constructor that doesn't have the same semantics as their assignment operator (operator ... error: object of type '(lambda at main.cpp:6:16)' cannot be assigned because its copy assignment operator is implicitly deleted. Lambdas don't even have an operator= to begin with (except in C++20 where they do if they ...

  17. Copy assignment operators (C++ only)

    The assignment x = y calls the implicitly defined copy assignment operator of B, which calls the user-defined copy assignment operator A::operator=(const A&).The assignment w = z calls the user-defined operator A::operator=(A&).The compiler will not allow the assignment i = j because an operator C::operator=(const C&) has not been defined.

  18. Copy assignment operator

    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

  19. Deleted functions(C++11)

    Deleted function declaration is a new form of function declaration that is introduced into the C++11 standard. To declare a function as a deleted function, you can append the =delete; specifier to the end of that function declaration. The compiler disables the usage of a deleted function. You can declare an implicitly defined function as a ...

  20. c++

    The reason the default definition of B's copy constructor is ill-formed is because - if it was permitted - it would invoke the private (therefore inaccessible to B) and not defined copy constructor of A. Make A's copy constructor either protected or public, so it is accessible to B.

  21. Copy assignment operators (C++ only)

    An implicitly defined copy assignment operator of a class A will first assign the direct base classes of A in the order that they appear in the definition of A. ... For more information, see Explicitly defaulted functions (C++11) and Deleted functions (C++11). Parent topic: Special member functions (C++ only) Related reference.