If I want to set the capacity to a std::vector
I have to call .reserve(...)
, are there any reason why there is not a capacity argument in the constructor for the containers in stl, std::string
, std::vector
?

- 9,493
- 13
- 51
- 66
-
1vector does have a constructor that takes a size – Apr 26 '11 at 14:47
3 Answers
There is one obvious reason: what would such a constructor look like?
All of the sequence containers already have a constructor that can be called with a single integer argument. That constructor resizes the container to have the specified number of elements.
Yes, you could add a second parameter (like bool reserve_instead_of_resize
) to be able to use this constructor for both initial resizes and initial reserves, but then I think the end result would be confusing.

- 348,265
- 75
- 913
- 977
-
It could take another, different integer parameter for the reserved size - except that would conflict with the different `const T &` parameter for the initial value in the case where `T = size_t` (and could be confused with it in other cases where one is convertible to the other). – Steve Jessop Apr 26 '11 at 15:42
-
1True. There is also the issue of consistency: reserve is only meaningful for vector, so we'd end up with another constructor just for vector. I think all (or most) of the other constructors are usable for all the sequence containers (though string does have some extra constructors, it is also less generic a container). For what it's worth, I rarely use reserve; it is occasionally useful as an optimization but not frequently enough, I think, to warrant another constructor. – James McNellis Apr 26 '11 at 15:53
-
2I very occasionally use `reserve` not as an optimization, but in order to prevent the semantic effects of re-allocation - iterator and pointer invalidation and the possibility of an exception. I agree it's not really worth a constructor, or rather a whole set of duplicates of the existing constructors. In the worst case I think you want to construct with non-trivial contents and also reserve, and you're scared of the cost of reallocation. So you need to construct empty, then reserve, then insert the contents. – Steve Jessop Apr 26 '11 at 16:01
-
1The question of what to use for a parameter could be answered with a wrapper class `std::reserve` that holds an integer. Still I have to agree that it wouldn't be worth it. – Mark Ransom Dec 05 '12 at 15:32
-
extra enum in the constructor, e.g. vector(size_t n, AllocType e = eResize). I would very much appreciate this since using the separate reserve call is not aesthetically optimized. – gast128 Jun 10 '16 at 13:12
You could simply make a function for creating a reserved vector:
// make_reserved_vector
template <typename... T>
std::vector<T...> make_reserved_vector(size_t n) {
std::vector<T...> vec;
vec.reserve(n);
return vec;
}
and use as:
auto myvec = make_reserved_vector<int>(32768);

- 1
- 1

- 12,825
- 5
- 58
- 90
-
4It's a great idea. This gets around the problem, but the C++ library still has an innate problem: you may have to pay for two memory allocations (the first vector constructor, when you have no idea what the default capacity is), and then the second (when you reserve and possible deallocate and reallocate). Your solution makes the best of this, but I think the C++ committee needs to revisit this problem. – rts1 Apr 01 '16 at 17:52
-
@rts1 : Exactly, that is my concern too. There might be one 'default size reserve' and then another reserve we call with. There could be multiple constructors for it, one taking the reserve size. – Piyush Soni Aug 21 '16 at 17:07
-
1quite old q/a, but somewhere I have to release my frustration ;) I dont get it why when choosing between initial capacity and initial size they choose size. If we could choose initial capacity, then size could be changed after construction without additional cost. As it is now, I either have to ask for a vector with a size that maybe I dont need or possibly pay twice to get the capacity I want. Imho thats against the first principle of C++, dont pay for what you dont need. Anyhow, your function is maybe the best way to deal with it – 463035818_is_not_an_ai Apr 12 '17 at 11:34
To create a vector, and specifying its capacity in the same time, create a vector with the wanted capacity, copy into it elements you want, and erase from the iterator returned by copy. If the constructor is slow, just write another constructor with special parameters that just reserves memory.
int main (int argc, char** argv) {
std::vector<size_t> v (10, 0);
size_t tmp [3] = {0, 1, 2};
std::vector<size_t>::iterator i (v.begin ());
i = std::copy ((const size_t*)tmp, (const size_t*) &tmp [3], v.begin ());
v.erase (i, v.end ());
std::cout << "\tv capacity == " << v.capacity () << std::endl;
}
will output :
v capacity == 10

- 306
- 3
- 16
-
If the elements' constructors have side-effects (or are simply slow), then this has different behaviour to creating an empty vector and then reserving some capacity. – Toby Speight Feb 21 '17 at 10:25
-
If the contructer is slow, create a foo constructor in your class that just reserves memory – Saint-Martin Feb 21 '17 at 12:02