C++ 11用例用于对和元组的piecewise_construct?

tow*_*owi 33 tuples forwarding use-case piecewise c++11

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
};
Run Code Online (Sandbox Code Playgroud)

然后,我想到标准对构造会失败:

pair<NoCopy,NoCopy> x{ NoCopy{1,2}, NoCopy{2,3} }; // fine!
Run Code Online (Sandbox Code Playgroud)

但事实并非如此.实际上,这是我所期望的,因为"移动东西"而不是在stdlib中的任何地方复制它应该是.

因此,我认为我没有理由这样做,或者说:

pair<NoCopy,NoCopy> y(
    piecewise_construct,
    forward_as_tuple(1,2),
    forward_as_tuple(2,3)
); // also fine
Run Code Online (Sandbox Code Playgroud)
  • 那么,什么是用
  • 我如何以及何时使用piecewise_construct

Joh*_*esD 34

并非所有类型都可以比复制更有效地移动,对于某些类型,甚至可以明确禁用复制和移动.考虑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});
Run Code Online (Sandbox Code Playgroud)

将上面的内容与必须创建然后复制的pair(big(1,2), big(3,4))两个临时big对象进行比较- 移动在这里根本没有帮助!同理:

std::vector<big> vec;
vec.emplace_back(1,2);
Run Code Online (Sandbox Code Playgroud)

分段构造一对的主要用例是将元素放入a mapunordered_map:

std::map<int, big> map;
map.emplace(std::piecewise_construct, /*key*/1, /*value*/{2,3});
Run Code Online (Sandbox Code Playgroud)

  • `map.emplace(std::piecewise_construct, /*key*/1, /*value*/{2,3});` 无法编译,应该使用 `map.emplace(std::piecewise_construct, std ::forward_as_tuple(1), std::forward_as_tuple(2,3));` 作为 `std::pair` 的适当构造函数是 `template&lt; class... Args1, class... Args2 &gt;pair(std: :piecewise_construct_t, std::tuple&lt;Args1...&gt; first_args, std::tuple&lt;Args2...&gt; secondary_args );` (3认同)
  • 你很好地描述了这一点,谢谢.和我想的一样.但是,如果你禁止移动目标类**(使用`= delete`),`pair(piecewise_construct,...)`将不起作用.我用gcc-4.7.0尝试了它,*得到了编译错误*.原因:执行`pair`:<br>`模板<class ... _Args1,class ... _Args2> pair(piecewise_construct_t,tuple <_Args1 ...> __ first,tuple <_Args2 ...> __second):first (__cons <first_type>(std :: move(__ first))),second(__ cons <second_type>(std :: move(__ second))){}`正如您所见,**移动**是必需的.**似乎没有使用**. (2认同)