私はコピーを持って/クラスプロービング移動:なぜstd :: vectorは初期化時にコピーを強制しますか?
#include <iostream>
struct A
{
A()
{
std::cout << "Creating A" << std::endl;
}
~A() noexcept
{
std::cout << "Deleting A" << std::endl;
}
A(const A &)
{
std::cout << "Copying A" << std::endl;
}
A(A &&) noexcept
{
std::cout << "Moving A" << std::endl;
}
A &operator=(const A &)
{
std::cout << "Copy-assigning A" << std::endl;
return *this;
}
A &operator=(A &&) noexcept
{
std::cout << "Move-assigning A" << std::endl;
return *this;
}
};
そして、私が実行していることを発見した:
#include <vector>
int main(int, char **)
{
std::vector<A> v { A() };
}
を
すると、次の出力を生成します。
Creating A
Copying A
Deleting A
Deleting A
なぜ初期化しませんオブジェクトを移動するだけですか?私はstd::vector
がundesired copies on resizeを作成することがありますが、ご覧のとおり、noexcept
を追加すると、ここで助けにならなかったことがわかりました(また、サイズ変更によってコピーが初期化される理由もないと思います)。
私の代わりに次の操作を行う場合は、次の
std::vector<A> v;
v.push_back(A());
私はコピーを得ることはありません。
GCC 5.4およびClang 3.8でテスト済みです。
これは 'std :: initializer_list'コンストラクタが使用されているためです。そのタイプのセマンティクスは残念です。 – StoryTeller
このQ/Aでは状況を説明し、いくつかの回避策を提供しています:https://stackoverflow.com/questions/8468774/can-i-list-initialize-a-vector-of-move-only-type –
@StoryTeller @MM Iそれで、問題は 'std :: vector'ではなく' std :: initializer_list'であり、明らかにrvalue参照を転送できません。誰かが適切な回答を投稿してくれたら、私はそれを受け入れます。 – jdehesa