Why is that the single parameter constructor of std::list<T>
requires T
to be a default-constructible type? I mean the following code does not compile.
struct Foo { // does not have default constructor.
Foo (int i) {}
}
int main(void) {
std::list<Foo> l(10);
}
It seems possible to use the construct and destroy idioms as they have already done in the std::vector, albeit with more book-keeping the list class.
On a related note, why not have the capacity function in list? You can argue that such a function would pay memory allocation cost up-front and eliminate the overhead later on as you push_back
objects. At least it will make the interfaces of two STL sequence containers slightly more consistent.
Because this contructor - creates list with elements (number which you pass as parameter). Value of each element will be default. Also you could use constructor with two parameters, for create list with elements which will be initialized with second element value.
It doesn't have sense, because cost of adding new elements to list is much little than in case with vector.
It is not restriction. Because if you don't use such constructor, default initializer will not required. Same thing true for vector.
Neil already answered the main question.
Also note that you need a default constructor when calling resize().
You can circumvent this by having a STL list of pointers to objects but I guess this already was obvious to you.
I guess the problem here is that STL lists allow cross-list splicing. If you want to allocate memory upfront, have a look at the Boost Pool Allocator.
std::list doesn't have a capacity function because it makes no sense; it never has to resize like a vector does. It's capacity is only limited by the available memory, which is not easily determined.
From what you asked for, I think you actually want reserve(). That's a one-off for vector because it (badly) needs such a thing; there's no particular requirement to make all functions consistent across all STL containers, especially when they make little sense for others.
You can accomplish the same effect using a custom allocator. As Manuel suggested, look at boost.
There is no general requirement that the type be default constructible - it must be copyable and assignable. Your code does not work because you try to create a list of 10 items - they have to be constructed somehow and so the default constructor must be used - but only in this specific case. If you created an empty list and added to it, there would be no such requirement.
The same is true for other containers - try compiling the following:
Regarding the second part of your question, I'd just observe that consistency of interface was not a prime design criterion for the standard containers - there is no intention, for example, that one type of container is a "drop-in" replacement for another. There is a good discussion of this in items 1 and 2 of Scott Meyers' book "Effective STL".
The reason is that, when you construct a list of n elements (where n is the parameter you used in the constructor), the list fills its structure of n elements with copies of T().
See sgi stl documentation for list.
So your question is really "why not have reserve and capacity functions in list?"
The answer to that is that there's no reason to reserve memory in advance for list - adding new elements never requires a realloc & copy for existing elements, there's no requirement that the memory holding the contents of a list be contiguous, and iterators don't get invalidated when doing a
list::push_back()
.All of those are the reason for the existence of
vector<>::reserve()
, and having memory in reserve for new elements is why avector<>
will perform placementnew
into raw memory.