Should copy assignment operator pass by const reference or by value?
Asked Answered
T

1

10

Prior to C++11, it has always been the case that copy assignment operator should always pass by const reference, like so:

template <typename T>
ArrayStack<T>& operator= (const ArrayStack& other);

However, with the introduction of move assignment operators and constructors, it seems that some people are advocating using pass by value for copy assignment instead. A move assignment operator also needs to be added:

template <typename T>
ArrayStack<T>& operator= (ArrayStack other);
ArrayStack<T>& operator= (ArrayStack&& other);

The above 2 operator implementation looks like this:

template <typename T>
ArrayStack<T>& ArrayStack<T>::operator =(ArrayStack other)
{
    ArrayStack tmp(other);
    swap(*this, tmp);
    return *this;
}

template <typename T>
ArrayStack<T>& ArrayStack<T>::operator =(ArrayStack&& other)
{
    swap(*this, other);
    return *this;
}

Is it a good idea to use pass by value when creating copy assignment operator for C++11 onwards? Under what circumstances should I do so?

Tusche answered 6/8, 2016 at 20:38 Comment(3)
operator=(ArrayStack) has no reason to create a copy tmp.Kosaka
slideshare.net/ripplelabs/howard-hinnant-accu2014 slides 43-53Harbird
The pass-by-value version can do both move and copy assignment, generally by copy-and-swap.Haworth
D
11

Prior to C++11, it has always been the case that copy assignment operator should always pass by const reference

That is not true. The best approach has always been to use the copy-and-swap idiom, and that's what you're seeing here (although the implementation in the body is sub-optimal).

If anything, this is less useful in C++11 now that you have a move assignment operator too.

Digestif answered 6/8, 2016 at 20:44 Comment(7)
So I guess nothing have changed, and it's still standard to provide both the copy assignment operator by const reference, and the move assignment operator right?Tusche
@Mantracker: You should read the linked answer. In fact, you should read this answer, too, based on your statement "it's still standard to provide both the copy assignment operator by const reference" which is in direct contradiction to what I've said.Digestif
I see, last time I read that answer it wasn't updated with C++ 11 if I remember correctly. Or maybe I didn't fully understand it, who knowsTusche
@Mantracker: That doesn't really matter because, as I've said a couple of times now, you are wrong even in C++03.Digestif
@LightnessRacesinOrbit Stroustrup seems to have missed this memo, in stroustrup.com/C++11FAQ.html all of his operator=s take const&s :). The operator=s in the standard also seem to be const basic_string& str, const deque& x, const unordered_multiset& and so forth?Gallopade
@kfsone: That's a C++11 FAQ, not a C++03 FAQ. I already stated that copy-and-swap is not as useful in C++11, so perhaps that's why. But, either way, asserting that either Bjarne or the standard library interface are the be-all-and-end-all of good, widely-established convention is ridiculous.Digestif
@LightnessRacesinOrbit, I also don't see any reason for passing const reference instead of by value (giving the advantages of copy-and-swap), but the Internet is indeed confusing: (1) Points in the consolidated C++ FAQ:isocpp.org/wiki/faq/coding-standards#lint-guidelines (2) Some past guidelines for operator=: web.archive.org/web/20161113144624/http://….Broadbrim

© 2022 - 2024 — McMap. All rights reserved.