在不触发默认构造函数且仅使用移动语义的情况下将向量从 N1 缩小到 N2 项
Shrink a vector from N1 down to N2 items without triggering the default constructor and using only move semantics
你能帮我用一种有效的方法将 std::vector<T>
从 N1
缩小到 N2
(N2 <= N1
) 个项目而不需要 T
有一个默认构造函数(即 resize()
不是一个选项,因为它需要一个默认构造函数,因为它也可以用来增长),并且只使用移动语义(不需要复制 constructor/assignment 运算符T
)?该操作是否实际缩小分配的内存是可选的(我还没有决定哪个更适合我的程序)。
到目前为止我尝试过的:
template<typename T> void Filter(vector<T> &v) {
// ... Filter the N1 items of the vector and move them to the first N2 positions
vector<T>(move(v)).swap(v); // this is wrong
}
这样的事情怎么样?
void foo(std::vector<T>& vec)
{
const std::size_t n = /* ... */;
std::vector<T>(
std::make_move_iterator(std::begin(vec)),
std::make_move_iterator(std::begin(vec) + n).swap(vec);
}
最简单的解决方案是擦除元素:
v.erase(v.begin() + N2, v.end());
如果需要,您可以减小保留大小:
v.shrink_to_fit();
您还可以使用 std::move
的其他重载来创建包含元素子集的新向量:
std::vector<T> filtered;
filtered.reserve(N2);
std::move(v.begin(), v.begin() + N2,
std::back_insert_iterator(filtered));
return filtered;
如果您需要就地完成,也许 erase
就足够了:
v.erase(v.begin() + N2, v.end());
erase
似乎更干净:
v.erase(v.begin() + N2, v.end());
但是 resize
的选项是提供一个虚拟对象:
auto& dummy = v[0]; // assuming non-empty, else create a new dummy object
v.resize(N2, dummy);
你能帮我用一种有效的方法将 std::vector<T>
从 N1
缩小到 N2
(N2 <= N1
) 个项目而不需要 T
有一个默认构造函数(即 resize()
不是一个选项,因为它需要一个默认构造函数,因为它也可以用来增长),并且只使用移动语义(不需要复制 constructor/assignment 运算符T
)?该操作是否实际缩小分配的内存是可选的(我还没有决定哪个更适合我的程序)。
到目前为止我尝试过的:
template<typename T> void Filter(vector<T> &v) {
// ... Filter the N1 items of the vector and move them to the first N2 positions
vector<T>(move(v)).swap(v); // this is wrong
}
这样的事情怎么样?
void foo(std::vector<T>& vec)
{
const std::size_t n = /* ... */;
std::vector<T>(
std::make_move_iterator(std::begin(vec)),
std::make_move_iterator(std::begin(vec) + n).swap(vec);
}
最简单的解决方案是擦除元素:
v.erase(v.begin() + N2, v.end());
如果需要,您可以减小保留大小:
v.shrink_to_fit();
您还可以使用 std::move
的其他重载来创建包含元素子集的新向量:
std::vector<T> filtered;
filtered.reserve(N2);
std::move(v.begin(), v.begin() + N2,
std::back_insert_iterator(filtered));
return filtered;
如果您需要就地完成,也许 erase
就足够了:
v.erase(v.begin() + N2, v.end());
erase
似乎更干净:
v.erase(v.begin() + N2, v.end());
但是 resize
的选项是提供一个虚拟对象:
auto& dummy = v[0]; // assuming non-empty, else create a new dummy object
v.resize(N2, dummy);