「一時オブジェクトを渡したときに移動できるようにするのね」と理解したつもりでコードを書いてみたけど、よく分からないところが…
#include <string> using namespace std; class Foo { string s; public: Foo(const char* cs) { cout << "constructor" << endl; } Foo(const Foo& foo) { cout << "copy constructor" << endl; } Foo(Foo&& foo) { cout << "move constructor" << endl; } }; void bar(Foo& foo) { cout << "copy bar" << endl; } void bar(Foo&& foo) { cout << "move bar" << endl; } void hl() { cout << "-----" << endl; } int main() { Foo foo1("test"); // constructorが呼ばれる hl(); Foo foo2(foo1); // copy constructorが呼ばれる hl(); Foo foo3_1(Foo("test")); // move constructorが…呼ばれない? hl(); Foo foo3_2 = Foo("test"); // これもだめ hl(); Foo foo3_3 = std::move(Foo("test")); // move constructorが呼ばれた… hl(); bar(foo1); // copy barが呼ばれる hl(); bar(Foo("test")); // move barが…呼ばれた。なんで? hl(); bar(std::move(Foo("test"))); // move barが呼ばれた return 0; }
「Foo foo3_1(Foo("test"));」でmove constructorが呼ばれと思ったら、呼ばれない。std::moveでくくったらmove constructorが呼ばれるようになったけど、「bar(Foo("test"));」との差がよく分からない。VC固有の動作かと思ったら、g++でも同じように動いた。
まだ名前を付けてないのに、なんで左辺値として扱われているんだろう?
追記
理由を少し考えてみた。
Foo foo3_1(Foo("test"));
上の例だと分かりにくいけど、下の場合
Foo foo3_2 = Foo("test"); // Foo foo3_2("test")と同じじゃね?
ふっつーにオブジェクトを作っているものと解釈されて、move constructorが呼ばれないんじゃないかなぁ、と推測。
つまり下の3つの書き方は全部同じ意味ですよ、と。
Foo foo("xxx"); Foo foo = Foo("xxx"); Foo foo(Foo("xxx"));
右と左で同じオブジェクト作って、即移動なんてないだろうから、当たり前のような気がする。
仕様書読むかなぁ。。。