For the following class with only move constructor:
class Foo {
public:
Foo(const Foo& foo) = delete;
Foo(Foo&& foo) = default;
Foo() = default;
};
Why would initializing a vector
with an initializing list like vector<Foo> vec{Foo()};
cause compilation error:
In file included from /usr/include/c++/11/vector:66,
from test_rand.cpp:3:
/usr/include/c++/11/bits/stl_uninitialized.h: In instantiation of ‘_ForwardIterator std::uninitialized_copy(_InputIterator, _InputIterator, _ForwardIterator) [with _InputIterator = const Foo*; _ForwardIterator = Foo*]’:
/usr/include/c++/11/bits/stl_uninitialized.h:333:37: required from ‘_ForwardIterator std::__uninitialized_copy_a(_InputIterator, _InputIterator, _ForwardIterator, std::allocator<_Tp>&) [with _InputIterator = const Foo*; _ForwardIterator = Foo*; _Tp = Foo]’
/usr/include/c++/11/bits/stl_vector.h:1585:33: required from ‘void std::vector<_Tp, _Alloc>::_M_range_initialize(_ForwardIterator, _ForwardIterator, std::forward_iterator_tag) [with _ForwardIterator = const Foo*; _Tp = Foo; _Alloc = std::allocator<Foo>]’
/usr/include/c++/11/bits/stl_vector.h:629:21: required from ‘std::vector<_Tp, _Alloc>::vector(std::initializer_list<_Tp>, const allocator_type&) [with _Tp = Foo; _Alloc = std::allocator<Foo>; std::vector<_Tp, _Alloc>::allocator_type = std::allocator<Foo>]’
test_rand.cpp:13:23: required from here
/usr/include/c++/11/bits/stl_uninitialized.h:138:72: error: static assertion failed: result type must be constructible from value type of input range
138 | static_assert(is_constructible<_ValueType2, decltype(*__first)>::value,
| ^~~~~
/usr/include/c++/11/bits/stl_uninitialized.h:138:72: note: ‘std::integral_constant<bool, false>::value’ evaluates to false
While there are no problems if I initialize an array
in the same way as array<Foo, 1> arr{Foo()};
.
I’d like to know:
- What does this error message actually mean: I’ve searched the usage of
is_constructible
, and it seems like it is testing whether you can construct an object with certain parameters. Then what are the parameters thatvector
is trying to verify for typeFoo
? - Why are the behaviors for
vector
andarray
different? - What is the internal process when constructing
vector
like this: I thought that it would be the same as calling.push_back
with an rvalue passed in, so that the move constructor could be called and it will induce no error. - Is it possible to make some modifications to the class
Foo
to make it work when constructing avector
with the initializing list? (without providing a copy constructor)