タプル/タイの場合の戻り値の最適化を見ています。私が観察した動作は期待通りではありません。以下の例では、移動セマンティクスがキックインされることを期待していますが、残っているコピー操作が1つあります。最適化で下からの出力は次のようになります。タプル/タイの戻り値の最適化
Test duo output, non_reference tuple
Default constructor invoked
Parameter constructor invoked
Copy constructor invoked
Move Assignment operator invoked
100
関数内のタプルを作るのコピーコンストラクタの呼び出しは不要と思われます。これを取り除く方法はありますか?私はMSVC 2012コンパイラを使用しています。
#include <iostream>
#include <tuple>
class A
{
public:
int value;
A() : value(-1)
{
std::cout << "Default constructor invoked" << std::endl;
}
explicit A(const int v) : value(v)
{
std::cout << "Parameter constructor invoked" << std::endl;
}
A(const A& rhs)
{
value = rhs.value;
std::cout << "Copy constructor invoked" << std::endl;
}
A(const A&& rhs)
{
value = rhs.value;
std::cout << "Move constructor invoked" << std::endl;
}
A& operator=(const A& rhs)
{
value = rhs.value;
std::cout << "Assignment operator invoked" << std::endl;
return *this;
}
A& operator=(const A&& rhs)
{
value = rhs.value;
std::cout << "Move Assignment operator invoked" << std::endl;
return *this;
}
};
std::tuple<A, int> return_two_non_reference_tuple()
{
A tmp(100);
return std::make_tuple(tmp, 99);
}
int main(int argc, char* argv[])
{
std::cout << "Test duo output, non_reference tuple" << std::endl;
A t3;
int v1;
std::tie(t3, v1) = return_two_non_reference_tuple();
std::cout << t3.value << std::endl << std::endl;
system("pause");
return 0;
}
単純なケースの良い選択肢ですが、もっと多くのアクションがtmpで実行され、出力が増えればうまく動作しません。そして、私はそれがMSVC 2012で動作するとは思わない。 – thorsan
コピーelionはここで起こっている。問題は、 'tmp'が' tuple'に移動していないことです。コピーコンストラクタはコピーされるタプルではなく、タプルに 'tmp'をコピーすることです。 – Simple
@シンプル私はそれを知っている、多分私の答えは十分ではない。 – TartanLlama