N3059 で、ペア(およびタプル)の区分的構造の説明を見つけました(これは新しい標準に含まれています)。
しかし、いつ使うべきかわかりません。 emplaceとコピー不可能なエンティティについての議論を見つけましたが、試してみたところ、が必要なケースを作成できませんでしたpiecewiese_construct
またはパフォーマンス上の利点が見られる可能性があります。
例。 コピー不可のクラスが必要だと思いましたが、movebale(転送に必要):
struct NoCopy {
NoCopy(int, int) {};
NoCopy(const NoCopy&) = delete; // no copy
NoCopy& operator=(const NoCopy&) = delete; // no assign
NoCopy(NoCopy&&) {}; // please move
NoCopy& operator=(NoCopy&&) {}; // please move-assign
};
次に、標準のペア構築が失敗することを予想しました。
pair<NoCopy,NoCopy> x{ NoCopy{1,2}, NoCopy{2,3} }; // fine!
しかし、そうではありませんでした。実際、これはとにかく私が期待していたことです。なぜなら、stdlibのどこにでもコピーするのではなく、「ものを移動する」ということです。
したがって、私がこれを行うべきだった理由はわかりません。
pair<NoCopy,NoCopy> y(
piecewise_construct,
forward_as_Tuple(1,2),
forward_as_Tuple(2,3)
); // also fine
piecewise_construct
を使用しますか?すべてのタイプをコピーよりも効率的に移動できるわけではありません。一部のタイプでは、コピーと移動の両方を明示的に無効にすることも意味があります。前者の種類のタイプの例として、_std::array<int, BIGNUM>
_を考えてみましょう。
emplace
関数と_piecewise_construct
_のポイントは、移動またはコピーする一時インスタンスを作成する必要なしに、そのようなクラスを構築できることですインプレース。
_struct big {
int data[100];
big(int first, int second) : data{first, second} {
// the rest of the array is presumably filled somehow as well
}
};
std::pair<big, big> pair(piecewise_construct, {1,2}, {3,4});
_
上記をpair(big(1,2), big(3,4))
と比較してください。ここでは、2つの一時的なbig
オブジェクトを作成してからコピーする必要があります。移動しても、ここではまったく役に立ちません。同様に:
_std::vector<big> vec;
vec.emplace_back(1,2);
_
ペアを区分的に構築する主な使用例は、要素をmap
または_unordered_map
_に配置することです。
_std::map<int, big> map;
map.emplace(std::piecewise_construct, /*key*/1, /*value*/{2,3});
_