给出以下C ++ 14代码:
struct A { /* heavy class, copyable and movable */ };
// complex code to create an A
A f(int);
A g(int);
A h(int);
const std::vector<A> v = { f(1), g(2), h(3) };
我知道初始化列表中的A
被复制到了向量中,而不是被移动(有很多问题)在stackoverflow中关于这个)。
我的问题是:我如何将移动到矢量中?
我只能做丑陋的IIFE(保持v
const)并且只是避免使用initializer_list:
const std::vector<A> v = []()
{
std::vector<A> tmp;
tmp.reserve(3);
tmp.push_back( f(1) );
tmp.push_back( g(2) );
tmp.push_back( h(3) );
return tmp;
}();
是否有可能使这个优雅的和高效?
PD:v
必须为std::vector<A>
以供日后使用
答案 0 :(得分:7)
不确定它是否算作&#34;优雅&#34;但是你可以使用一个数组(或std::array
),它使用不会遇到此问题的聚合初始化,并move_iterator
将值移到vector
。
std::array<A, 3> init = { f(1), g(2), h(3) };
std::vector<A> v{std::make_move_iterator(init.begin()),
std::make_move_iterator(init.end())};
答案 1 :(得分:2)
你问一个C ++ 14解决方案,所以你可以使用带有auto
参数的variadic lambda函数。
以lambda函数为例...
#include <vector>
struct A
{ };
A f (int) { return {}; }
A g (int) { return {}; }
A h (int) { return {}; }
int main ()
{
static const auto getVA = [](auto && ... args)
{
using unused = int[];
std::vector<A> ret;
ret.reserve(sizeof...(args));
(void)unused { 0,
(ret.emplace_back(std::forward<decltype(args)>(args)), 0)... };
return ret;
};
auto va = getVA(f(1), g(2), h(3));
}
如果您更喜欢旧类型(非lambda)函数,或者您想要一个也适用于C ++ 11的解决方案,getVA
可以编写如下
template <typename ... Args>
std::vector<A> const getVA (Args&& ... args)
{
using unused = int[];
std::vector<A> ret;
ret.reserve(sizeof...(args));
(void)unused { 0, (ret.emplace_back(std::forward<Args>(args)), 0)... };
return ret;
}