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?

Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055
Mantracker
  • 613
  • 10
  • 22

1 Answers1

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.

Community
  • 1
  • 1
Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055
  • 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? – Mantracker Aug 06 '16 at 20:48
  • @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. – Lightness Races in Orbit Aug 06 '16 at 20:49
  • 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 knows – Mantracker Aug 06 '16 at 20:52
  • @Mantracker: That doesn't really matter because, as I've said a couple of times now, you are wrong even in C++03. – Lightness Races in Orbit Aug 06 '16 at 20:54
  • @LightnessRacesinOrbit Stroustrup seems to have missed this memo, in http://www.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? – kfsone Aug 06 '16 at 21:08
  • 3
    @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. – Lightness Races in Orbit Aug 06 '16 at 21:17
  • @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:https://isocpp.org/wiki/faq/coding-standards#lint-guidelines (2) Some past guidelines for operator=: https://web.archive.org/web/20161113144624/http://courses.cms.caltech.edu/cs11/material/cpp/donnie/cpp-ops.html. – uvsmtid May 03 '20 at 11:29