给定以下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
在initializer_list中被复制到向量中,而不是被移动(在堆栈溢出中有很多问题)。
我的问题是:我如何将它们移动到向量中?
我只做了丑陋的生活(保持了v
康斯特),并避免了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>
发布于 2017-04-28 10:27:29
不确定它是否“优雅”,但您可以使用一个数组(或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())};
现场演示。
发布于 2017-04-28 11:46:39
您需要一个C++14解决方案,这样就可以使用带有auto
参数的变量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;
}
https://stackoverflow.com/questions/43677016
复制相似问题