When is copy-and-swap idiom not applicable
Asked Answered
S

2

13

After reading this about the copy-and-swap idiom I've read this which says under (2):

class_name & class_name :: operator= ( const class_name & )     (2)     

(2) Typical declaration of a copy assignment operator when copy-and-swap idiom cannot be used

When should we avoid using the copy-and-swap idiom ?

And when it "cannot be used" altogether?

Are there real life cases where both copy-and-swap and rule-of-zero are not applicable?

I did find this question but it was too specific and did not include any guideline as to how to identify such cases.

Stenophyllous answered 16/11, 2015 at 11:59 Comment(3)
Typically, copy-and-swap is easy and safe, but perhaps not optimal from a speed perspective. For example, assigning two containers of a million elements, it's probably faster to do a million assignments than to do a million constructions and a million destructions.Anole
@user2079303 thanks, that sentence was drunk it had to go home. Hope now it's clearerStenophyllous
Real life cases where copy/swap kills your performance: https://mcmap.net/q/907801/-should-copy-assignment-operator-leverage-std-swap-as-a-general-ruleEboh
H
7

When should we avoid using the copy-and-swap idiom ?

When you can prove that naïve copy is safe and faster than swap.

You can identify the case when there are no member pointers (neither smart nor raw) that own objects and same is true for all member objects.

And when it "cannot be used" altogether?

Copy-and-swap cannot be used when the type is not swappable.

To be swappable, the type must be either move-constructible and move-assignable, or you must have defined a swap member function or a friend function.

Hobbism answered 16/11, 2015 at 12:19 Comment(0)
S
2

Your link describing the potential implementations of an assignment operator described class_name& class_name::operator=(class_name) as:

Typical declaration of a copy assignment operator when copy-and-swap idiom can be used

And class_name& class_name::operator=(const class_name&) as:

Typical declaration of a copy assignment operator when copy-and-swap idiom cannot be used

Basically we would always want to use copy-and-swap when possible, as mentioned in the excellent answer to your linked question, because it will pass the self-assignment test.

So now the question is why the convention mentioned on http://www.cppreference.com?

Let's say I'm implementing a copy constructor to a virtual class, and I want to make it clear to anyone who will inherit that they should use the copy-and-swap idiom. How would I do that? I could help them by doing the copy for them in the initial call:

class_name& class_name::operator=(class_name)

This is a copy by value, so the implementer of any child classes would see that I've already made the copy for them so all they'll need to do is swap.

Now, what if I had a class_name which contained a member which could not be copy constructed, for example what if my class has a unique_ptr such that it cannot be copy-constructed. I can indicate that by not making a copy by value argument to the assignment operator, for example:

class_name& class_name::operator(const class_name&)

Indicating it will be on implementer of any child classes to ensure that sufficient checking is done to pass the self-assignment test.

Skateboard answered 16/11, 2015 at 12:23 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.