I\'ve read in several places that std::vector requires it\'s template argument to be default constructible. Today I just tried it with one of my classes that has a delete<
The requirement in C++03 is that types being stored in a container be CopyConstructible
and Assignable
(see §23.1 Container Requirements). However, in C++11 these requirements are relaxed, and tend to apply to the operations performed on the container. So a simple default construction has no requirements (see teble 96, §23.1 in C++11 standard).
As soon as you try to copy a vector, or insert elements into it, you will meet the CopyInsertable
, CopyAssignable
, EmplaceConstructible
, MoveInsertable
, MoveAssignable
etc. requirements
Well, templates are in some meaning weakly typed. That is, the missing default constructor won't be detected until your code calls the method where it's used, perhaps internally -- this will give a compile-time error.
However, unless you are not touching the methods which use the default constructor internally, you are "safe". However, I don't know which is the "safe" subset, and I suspect that it's not defined by the standard. Example: vector copying might use resize
, which in turn might use default constructor.
There are two vector<T>
members that require a default constructible T
in C++11:
explicit vector(size_type n);
void resize(size_type sz);
Nothing else does. So if you use these signatures, you need to have a default constructible type, else you do not.
std::vector
does not unconditionally require its elements type to be default-constructible.
The original specification of std::vector
(C++98, C++03) never even attempts to default-construct its elements internally. All new elements are always copy-constructed from an object supplied "from outside" (by the calling code) as an argument. This means that every time you need default-constructed elements in your vector, it is your side of the code (the caller) that has to default-construct it and supply it to std::vector
as the "original" element to be copied.
For example, when you do something like this in C++98
std::vector<some_type> v(42);
v.resize(64);
it actually expands into
std::vector<some_type> v(42, some_type(), allocator_type());
v.resize(64, some_type());
through the default argument mechanism. In other words, the default-constructed "original" element is supplied to vector's constructor by the calling code, not created internally by the vector.
C++11 changed that and now std::vector
has methods that perform default construction of its elements internally. This still does not unconditionally require vector elements to be default-constructible. It just means that you need default-constructible elements to use those specific std::vector
's methods.