Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How is it possible to construct a std::vector of non-default constructible objects?

Tags:

c++

c++11

I came across code like this from the C++ reference page:

#include <algorithm>
#include <list>
#include <vector>
#include <functional>

int main()
{
    std::list<int> l = {-4, -3, -2, -1, 0, 1, 2, 3, 4};
    std::vector<std::reference_wrapper<int>> v(l.begin(), l.end());
    return 0;
}

This is a snippet from the "Examples" section. The code compiles and runs as expected. But how is it possible? The std::reference_wrapper<int> is not default constructible. How can you make a std::vector of those things? I always imagined std::vector as a dynamic array. But how can you initialize a block of memory freshly given to you by OS in such a way from a std::list?

This may sound like a confusing question, but for some reason I cannot fully understand what is happening in the code above. What is going on in there?

like image 855
Martin Drozdik Avatar asked Dec 05 '25 11:12

Martin Drozdik


2 Answers

It works because there's no default initialization there - the elements from the list are used to copy-initialize the vector.

The following, for example, wouldn't work:

std::vector<std::reference_wrapper<int>> v(42);
like image 183
Luchian Grigore Avatar answered Dec 06 '25 23:12

Luchian Grigore


The constructor of std::vector<> first obtains a block of raw memory of appropriate size (using its allocator). It then constructs the objects. In case of the particular constructor here

template<typename It>
std::vector::vector(It begin, It end);

it constructs the elements from the valuetype of the iterators, thus each reference_wrapper<int> is constructed (in place) from an int.

like image 20
Walter Avatar answered Dec 06 '25 23:12

Walter



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!