问题
I have a std::vector
named args
(I don’t know the size of the vector at compile time) and a non movable type NonMoveable
.
I want to create a vector of the same size as args, so that it equals to
{NonMovable(args[0], additional_arg), NonMovable(args[1], additional_arg), …, NonMovable(args.back(), additional_arg)}
I don’t need to change the size of the vector later. How do I do that?
I can’t reserve()
then emplace_back()
because emplace_back()
requires moving (to allow reallocation which is not possible in my case)
I do not want to use std::list
because it is not contiguous.
回答1:
You can:
- Have a
vector<unique_ptr<T>>
orvector<optional<T>>
orvector<some_other_defer_storage_mechanism<T>>
instead of justvector<T>
- these are all wrapper types that adding some functionalityT
without affectingT
(unique_ptr<T>
makes it movable,optional<T>
ensures default construction so you can construct with the right size thenemplace()
within theoptional
, etc.) - Use
deque<T>
which does not require movability foremplace_back
(although you lose Contiguity) - Write your own dynamic array that is roughly equivalent to a
pair<unique_ptr<T[]>, size_t>
that just allocates space forn
T
s and then placement-news onto each of them, ensuring that destruction does the right thing. This isn't so bad to implement - since you won't be changing the size, you need to support a very minimal amount of overall operations.
Whichever one of these is the best answer really depends.
回答2:
If you want the elements to be contiguous, you could use the good old 2 times dynamic array construction:
// allocate a dynamic array
NonMoveable *mv = std::allocator<NonMoveable>().allocate(args.size());
// use inplace new to construct the NonMoveable elements
for (unsigned int i = 0; i < args.size(); i++) {
new(mv + i) NonMoveable(args[i], additional_arg);
}
... // use the dynamic array
// Explicitely delete the elements
for (unsigned int i = 0; i < args.size(); i++) {
mv[i].~NonMoveable();
}
// and de-allocate
std::allocator<NonMoveable>().deallocate(mv, args.size());
It is rather C-ish but meets the contiguous requirement. Of course this should be encapsulated in a custom container to allow automatic destruction and de-allocation at container destruction.
来源:https://stackoverflow.com/questions/54953039/creating-stdvector-of-nonmovable-type