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.