Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

std::vector works with classes that are not default constructible?

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 deleted 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?

like image 603
Cubic Avatar asked Aug 01 '12 16:08

Cubic


People also ask

Can vector store different types?

Vectors allow you to store more than one value in a single data structure that puts all the values next to each other in memory. Vectors can only store values of the same type.

How to Initialize a vector in a class c++?

Initialize Vector in ConstructorDeclare vec of vector type. Declare a constructor of vector class. Pass a vector object v as a parameter to the constructor. Initialize vec = v.

What does std :: vector do?

1) std::vector is a sequence container that encapsulates dynamic size arrays. 2) std::pmr::vector is an alias template that uses a polymorphic allocator. The elements are stored contiguously, which means that elements can be accessed not only through iterators, but also using offsets to regular pointers to elements.

How to declare vector in c++ class?

Syntax for Vectors in C++Every new vector must be declared starting with the vector keyword. This is followed by angle brackets which contain the the type of data the vector can accept like strings, integers, and so on. Lastly, the vector name - we can call this whatever we want.


3 Answers

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

like image 135
juanchopanza Avatar answered Oct 27 '22 01:10

juanchopanza


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.

like image 26
AnT Avatar answered Oct 27 '22 00:10

AnT


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.

like image 20
Howard Hinnant Avatar answered Oct 27 '22 00:10

Howard Hinnant