私はこのコードを持っています:
#include <iostream>
#include <vector>
using namespace std;
class Foo{
public:
Foo() noexcept {cout << "ctor" << endl;}
Foo(const Foo&) noexcept {cout << "copy ctor" << endl;}
Foo(Foo&&) noexcept {cout << "move ctor" << endl;}
Foo& operator=(Foo&&) noexcept {cout << "move assn" << endl; return *this;}
Foo& operator=(const Foo&) noexcept {cout << "copy assn" << endl; return *this;}
~Foo() noexcept {cout << "dtor" << endl;}
};
int main()
{
Foo foo;
vector<Foo> v;
v.push_back(std::move(foo));
// comment the above 2 lines and replace by
// vector<Foo> v{std::move(foo)};
}
g++ -std=c++11 --no-elide-constructors
出力は私が期待するものです(フラグなしで同じ出力でコンパイルされます)
ctor
move ctor
dtor
dtor
ベクトルをpush_back
直接初期化する代わりに、v
vector<Foo> v{std::move(foo)};
出力が得られる理由がわかりません:
1) (なし--no-elide-constructors
)
ctor
move ctor
copy ctor
dtor
dtor
dtor
2) (と--no-elide-constructors
)
ctor
move ctor
move ctor
copy ctor
dtor
dtor
dtor
dtor
最初のケースでは、なぜ copy ctor が呼び出されるのでしょうか? そして 2 番目のケースでは、コンパイラが省略を実行しない場合、move ctor が 2 回呼び出される理由がまったくわかりません。何か案は?