46

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ますか?
4

2 に答える 2

49

すべてのタイプをコピーよりも効率的に移動できるわけではありません。一部のタイプでは、コピーと移動の両方を明示的に無効にすることも意味があります。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);

ペアを区分的に構築するための主なユースケースは、要素をamapまたはunordered_map:に配置することです。

std::map<int, big> map;
map.emplace(std::piecewise_construct, /*key*/1, /*value*/{2,3});
于 2011-05-28T17:40:51.880 に答える