Reputation: 15683
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
d default constructor, and to my surprise it seems to be working just fine (with std::vector's default constructor). Is this portable behavior, or is this an implementation detail of gcc's STL and should I assume vector to require it's template argument to be default constructible?
Upvotes: 12
Views: 5010
Reputation: 219185
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.
Upvotes: 22
Reputation: 320631
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.
Upvotes: 8
Reputation: 227468
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
Upvotes: 15
Reputation: 35594
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.
Upvotes: 4