Search code examples
c++c++17swapmove-semantics

swap and move infinite recursion


I have a very simple example class, compiled with C++17.

#include <string>
#include <iostream>

struct name {
    std::string first, middle, last;
    name() = default;
    name(name const&) = default;
    name(name &&) = default;

    name& operator=(name o) {
        std::swap(*this, o); // bad!
        return *this;
    }
};
int main() {
    name n1{"mr", "john", "smith"};
    name n2 = std::move(n1); 
    name n3 = n2;

    std::cout << n3.first << " " << n3.middle << " " << n3.last;
} 

Using this value-semantics, bundled move assignment and I deliberately called qualified swap, instead of using std::swap; swap(*this, o);. I didn't provide my swap anyways. Thinking that STL implements swap as a move construction and series of move assignments, I thought this implementation would infinitely recurse, swap calling move and move calling swap. Is std::swap changed into member-wise swap or something like that?


Solution

  • You never invoked operator=; all of your code is using initialization (which invokes constructors), specifically copy initialization, not assignment (which invokes operator=).

    Change the code to:

    name n1{"mr", "john", "smith"};
    name n2, n3;
    
    n2 = std::move(n1); 
    n3 = n2;
    

    and you'll see your operator= used (and presumably explode).