我注意到,当move更适用时,std :: vector的aggregate list初始化会执行复制初始化。同时,多个emplace_backs可以满足我的要求。
我只能提出编写模板函数init_emplace_vector
的不完善解决方案。不过,它仅对non-explicit single-value构造函数最佳。
template <typename T, typename... Args> std::vector<T> init_emplace_vector(Args&&... args) { std::vector<T> vec; vec.reserve(sizeof...(Args)); // by suggestion from user: eerorika (vec.emplace_back(std::forward<Args>(args)), ...); // C++17 return vec; }
问题
我真的需要使用emplace_back来尽可能高效地初始化std :: vector吗?
// an integer passed to large is actually the size of the resource std::vector<large> v_init { 1000, // instance of class "large" is copied 1001, // copied 1002, // copied }; std::vector<large> v_emplaced; v_emplaced.emplace_back(1000); // moved v_emplaced.emplace_back(1001); // moved v_emplaced.emplace_back(1002); // moved std::vector<large> v_init_emplace = init_emplace_vector<large>( 1000, // moved 1001, // moved 1002 // moved );
输出
Class large
产生有关复制/移动的信息(下面的实现),因此我的程序输出为:
- initializer large copy large copy large copy - emplace_back large move large move large move - init_emplace_vector large move large move large move
大类实现
我对large
的实现只是一个可复制/可移动类型,其中包含警告复制/移动的大型资源。
struct large { large(std::size_t size) : size(size), data(new int[size]) {} large(const large& rhs) : size(rhs.size), data(new int[rhs.size]) { std::copy(rhs.data, rhs.data + rhs.size, data); std::puts("large copy"); } large(large&& rhs) noexcept : size(rhs.size), data(rhs.data) { rhs.size = 0; rhs.data = nullptr; std::puts("large move"); } large& operator=(large rhs) noexcept { std::swap(*this, rhs); return *this; } ~large() { delete[] data; } int* data; std::size_t size; };
编辑
通过使用保留,没有副本或移动。仅调用large::large(std::size_t)
构造函数。真正的位置。
我注意到,在更适合移动时,std :: vector的聚合列表初始化会执行复制初始化。同时,多个emplace_backs可以满足我的需求。我只能上来...
我可以聚合初始化std :: vector ...