Could you help me with an efficient way to shrink an std::vector<T>
from N1
down to N2
( N2 <= N1
) items in it without requiring T
to have a default constructor (ie resize()
is not an option because it requires a default constructor because it can be used to grow also), and using only move semantics (without requiring a copy constructor/assignment operator in T
)? Whether the operation actually shrinks the allocated memory is optional (I haven't yet decided which one is better for my program).
What I have tried so far:
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
}
What about something like this?
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);
}
Simplest solution is to erase the elements:
v.erase(v.begin() + N2, v.end());
You can reduce the reserved size if desired:
v.shrink_to_fit();
You can also use the other overload of std::move
to create a new vector containing the subset of elements:
std::vector<T> filtered;
filtered.reserve(N2);
std::move(v.begin(), v.begin() + N2,
std::back_insert_iterator(filtered));
return filtered;
If you need to do it in-place, maybe just erase
will be enough:
v.erase(v.begin() + N2, v.end());
erase
seems the cleaner:
v.erase(v.begin() + N2, v.end());
but option with resize
is to provide a dummy object:
auto& dummy = v[0]; // assuming non-empty, else create a new dummy object
v.resize(N2, dummy);
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.