2

I have this code:

#include <iostream>
#include <string>

using namespace std;

class S
{
public:

  S(std::string && s)
  : str(std::move(s))
  {
  }

  /* Why does a copy of s happen somewhere in here? */
  S(std::string && s, bool dummyArg)
  : str(s)
  {
  }

  void printVal() const
  {
    cout << "S::s is \"" << str << "\"\n";
  }

private:
  string str;
};


int main(int argc, const char * argv[])
{
  string str1{"Some string that I want to move into S"};
  string str2{"Some other string that I want to move into S"};

  // S s0{str1}; // Does not compile because no constructor matches
  S s1{std::move(str1)};
  S s2{std::move(str2), false};

  s1.printVal();
  cout << "str1 is: \"" << str1 << "\"\n";

  cout << "\n";

  s2.printVal();
  cout << "str2 is : \"" << str2 << "\"\n";
}

Which produces the following output: (compiled with Clang (XCode 9))

S::s is "Some string that I want to move into S"
str1 is: ""

S::s is "Some other string that I want to move into S"
str2 is : "Some other string that I want to move into S"

So we can clearly see that when using the second constructor, str2 isn't moved into S::str. I do not understand why adding an std::move makes a difference as std::move is just does a static_cast<T&&> on its arguments, which is already the type of the constructor's argument.

op414
  • 582
  • 5
  • 15

0 Answers0