重複の可能性:
移動専用型のベクトルをリスト初期化できますか?
編集 1: 再投票を検討してください: 私の質問はインプレース建設を強調しています。ムーブ コンストラクションは代替案ですが、この質問の対象ではありません。答えてくれてありがとう!
編集 2: この質問に答えられないので (締め切られました)、私自身の提案をここに投稿します。以下は、私が受け入れた回答ほど良くはありませんが、他の人にとっては役立つかもしれません。少なくとも move コンストラクターのみが呼び出されます。
std::vector<A2> vec;
{
std::array<A2,3> numbers{{{2,3},{5,6},{7,8}}};
vec.reserve(numbers.size());
for (auto &v: numbers) vec.emplace_back(std::move(v)) ;
}
元の投稿:
ベクトルの STL 配列内でのクラスの初期化という質問への答えを考えたとき、初期化リストからベクトルのインプレース構築を取得する方法が見つからないことがわかりました。私は何が欠けていますか?
より明確にするために、この(完全に正しい)初期化が必要です
std::vector<A2> k{{2,3},{4,5},{8,9}};
これに似た効果を得るには:
std::vector<A2> k2;
k2.reserve(3);
k2.emplace_back(2,3);
k2.emplace_back(4,5);
k2.emplace_back(8,9);
ただし、最初のケースでは、挿入中に一時的に A2 に対してコピーコンストラクターが呼び出されます。それを回避する方法はありますか?基準は何と言っていますか?
必死にやってみた
std::vector<A2> k{{2,3},{4,5},std::move(A2{8,9})};
しかし、それは移動コンストラクターへの追加の呼び出しを生成します。これも私が予期していなかったものです。A2 が一時的なものであることを明示的にほのめかしたかっただけで、暗示されていると思っていたものです。
完全な例:
#include <vector>
#include <iostream>
struct A2 {
int mk;
int mj;
A2(int k,int j) : mk(k),mj(j) {
std::cout << " constr for "<<this<< ":"<< mk<<std::endl;
}
A2(const A2& a2) {
mk=a2.mk;
mj=a2.mj;
std::cout << "copy constr for "<<this<< ":" << mk<<std::endl;
}
A2(A2&& a2) noexcept {
mk=std::move(a2.mk);
mj=std::move(a2.mj);
std::cout << "move constr for "<<this<< ":"<< mk<<std::endl;
}
};
struct Ano {
Ano() {
std::cout << " constr for "<<this <<std::endl;
}
Ano(const Ano& ano) {
std::cout << "copy constr for "<<this<<std::endl;
}
Ano(Ano&& ano) noexcept {
std::cout << "move constr for "<<this<<std::endl;
}
};
int main (){
// here both constructor and copy constructor is called:
std::vector<A2> k{{2,3},{4,5},std::move(A2{8,9})};
std::cout << "......"<<std::endl;
std::vector<A2> k2;
k2.reserve(3);
// here (naturally) only constructor is called:
k2.emplace_back(2,3);
k2.emplace_back(4,5);
k2.emplace_back(8,9);
std::cout << "......"<<std::endl;
// here only constructor is called:
std::vector<Ano> anos(3);
}
出力:
constr for 0xbf9fdf18:2
constr for 0xbf9fdf20:4
constr for 0xbf9fdf0c:8
move constr for 0xbf9fdf28:8
copy constr for 0x90ed008:2
copy constr for 0x90ed010:4
copy constr for 0x90ed018:8
......
constr for 0x90ed028:2
constr for 0x90ed030:4
constr for 0x90ed038:8
......
constr for 0x90ed048
constr for 0x90ed049
constr for 0x90ed04a