私はC++で移動コンストラクタを理解することが困難でした。私は既定のコンストラクタ、コピーコンストラクタ、移動コンストラクタ、およびデストラクタを使用して簡単なクラスを作成しました。また、2つのオーバーロードを持つ関数を定義しました。そのクラスへの参照を受け取り、そのクラスへの参照値を受け入れます。私のテストコードは以下の通りです。移動コンストラクタとの混乱:移動コンストラクタを呼び出すことができません
#include <iostream>
class c {
public:
c() {
std::cout << "default constructor" << std::endl;
}
c(const c& s) {
std::cout << "copy constructor" << std::endl;
}
c(c&& s) {
std::cout << "move constructor" << std::endl;
}
~c() {
std::cout << "destructor" << std::endl;
}
};
void f(c& s) {
std::cout << "passed by reference" << std::endl;
}
void f(c&& s) {
std::cout << "passed by rvalue reference" << std::endl;
}
int main() {
c s1; // line 1
std::cout << "\n";
c s2(s1); // line 2
std::cout << "\n";
c s3(c()); // line 3
std::cout << "\n";
f(s1); // line 4
std::cout << "\n";
f(c()); // line 5
getchar();
return 0;
}
出力は私が期待していたものではありません。以下は私がこのコードから得ている出力です。
default constructor
copy constructor
passed by reference
default constructor
passed by rvalue reference
destructor
line 3
を除くすべての行の出力を理解できます。 であるline 3
で、c()
は値ですので、私はs3
が構築されることを期待しています。しかし、アウトプットには、それが建設されたことが示されていない。 line 5
で、私は同じことをしており、を関数f()
に渡しています。実際にはrvalue
の参照を受け付けるオーバーロードを呼び出します。私は非常に混乱しており、これに関する情報は感謝しています。
編集:c s3(std::move(c()));
を実行すると移動コンストラクタを呼び出すことができますが、まだrvalueをs3に渡していませんか?なぜ私はstd::move
が必要でしょうか?
は本当にこの1の複製ではありません。ここで起こっているのは、Elisationをコピーするのではなく、Most Vexing Parseです。 – Angew
@Angew良いお電話。それを逃した。 – NathanOliver
@Angew私が実際にやろうとしたのは、移動コンストラクタを使ってオブジェクトを構築することでした.NathanOliverが私を別の質問に導いたとき、私は本当にこれが重複していると考えました。あなたが指摘するまで、3行目のステートメントが関数シグネチャであることに気付かなかった。私は一度も煩わしさを聞いたことがないので、それを私と共有してくれてありがとう。私はそれが何であるかを知るためにそれを読んでいます。 – Deniz