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?
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);
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With