It\'s an exercise from C++ Primer 5th Edition:
Exercise 16.26: Assuming NoDefault is a class that does not have a default constructor, can we e
C++11 introduces a new constructor, vector(size_type n)
, and "obviously" that constructor can't be instantiated unless the value_type
is default-constructible. It was vector(size_type n, const T & = T(), const Allocator& alloc = Allocator())
in C++03, but they changed it to two separate constructors. A similar change was made to resize()
.
In GCC and as far as I know also per the standard: the vector
template can be at least implicitly instantiated without the elements being default constructible. Implicit template class instantiation only instantiates the member functions you use.
In C++03 only the default arguments use default construction. You can explicitly instantiate the template, but you won't be able to call those functions without providing a value for that parameter.
So I'm pretty sure that change is what prevents vector<NoDefault>
being explicitly instantiated in C++11 (and I suppose the allocator type needs to be default-constructible too). But I might have missed something. It seems a little odd to make that change given that it introduces this backward incompatibility. There's probably a proposal somewhere that justifies it if you want a deeper reason why this no longer works as opposed to just why this doesn't work :-)
While explicitly instantiating
std::vector<someType>
, what is the someType default constructor used for?
It's used to construct the elements of the array when resizing the std::vector
. For example:
std::vector<T> vector(10);
will default construct 10 elements of type T
.
As already said, the default constructor is required to create vector of objects. However, if one were to create a classic dynamic array (contiguous area of memory), it would be possible to address the lack of a default constructor using the placement new syntax:
#include <iostream>
struct Foo {
explicit Foo(int a): a(a) {}
int a;
};
int main() {
void* mem = operator new[](10*sizeof(Foo));
Foo* ptr = static_cast<Foo*>(mem);
for (int i = 0; i < 10; ++i ) {
new(&ptr[i])Foo(i);
std::cout << ptr[i].a;
}
return 0;
}