Код
#include <list>
#include <memory>
class B;
class A {
std::list<std::unique_ptr<B>> bs;
public:
A();
~A();
};
int main()
{
A x;
return 0;
}
очевидно компилируется. Это не связано, потому что A::A() и A::~A() отсутствуют, но это ожидаемо и хорошо. изменение
std::list<std::unique_ptr<B>> bs;
который должен вызывать стандартный конструктор std::list
list() : list(Allocator()) {}
(С++ 14 и выше) до
std::list<std::unique_ptr<B>> bs{};
который должен вызывать list(std::initializer_list, const Allocator & = Allocator()); также конструктор по умолчанию. (Спасибо Nicol Bolas, который правильно сослался на [over.match.list] 13.3.1.7) дает следующую ошибку с c++ (Ubuntu 5.2.1-22ubuntu2) 5.2.1 20151010< /strong> и параметр --std=c++17:
/usr/include/c++/5/bits/unique_ptr.h: In instantiation of ‘void std::default_delete<_Tp>::operator()(_Tp*) const [with _Tp = B]’:
/usr/include/c++/5/bits/unique_ptr.h:236:17: required from ‘std::unique_ptr<_Tp, _Dp>::~unique_ptr() [with _Tp = B; _Dp = std::default_delete<B>]’
/usr/include/c++/5/bits/stl_list.h:106:12: required from ‘void __gnu_cxx::new_allocator<_Tp>::destroy(_Up*) [with _Up = std::_List_node<std::unique_ptr<B> >; _Tp = std::_List_node<std::unique_ptr<B> >]’
/usr/include/c++/5/bits/list.tcc:75:4: required from ‘void std::__cxx11::_List_base<_Tp, _Alloc>::_M_clear() [with _Tp = std::unique_ptr<B>; _Alloc = std::allocator<std::unique_ptr<B> >]’
/usr/include/c++/5/bits/stl_list.h:446:17: required from ‘std::__cxx11::_List_base<_Tp, _Alloc>::~_List_base() [with _Tp = std::unique_ptr<B>; _Alloc = std::allocator<std::unique_ptr<B> >]’
/usr/include/c++/5/bits/stl_list.h:507:11: required from here
/usr/include/c++/5/bits/unique_ptr.h:74:22: error: invalid application of ‘sizeof’ to incomplete type ‘B’
static_assert(sizeof(_Tp)>0,
^
Который лает о том, что тип B неполный. Мой вопрос:
Почему конструктору initializer_list нужен полный тип B для пустого списка инициализаторов?
Всегда приветствуются указатели на соответствующие части стандарта.
unique_ptrнужен полный тип, см. stackoverflow.com/questions/9954518/ @Jarod42 Вы должны опубликовать ответ, так как это хороший вопрос и не такой очевидный. - person vsoftco   schedule 29.01.2016std::list<std::unique_ptr<B>> bs{};вызовет конструктор по умолчанию. В соответствии с 13.3.1.7 стандарта C++14, если пустой список инициализации в фигурных скобках передается типу, имеющему конструктор по умолчанию, то именно он и будет вызываться. - person Nicol Bolas   schedule 29.01.2016std::list<std::unique_ptr<B>> bs;тоже должен вызывать конструктор по умолчанию, верно? Почему тогда не работает тот, что с{}? - person apriori   schedule 29.01.2016std::list<std::unique_ptr<B>> bs;не вызывает никакого конструктора. - person T.C.   schedule 29.01.2016struct X { X() = delete; }; class A { X x; }; int main() { A a; return 0; }определенно не работает. - person apriori   schedule 30.01.2016struct X <% X(int); %>; class A <% X x; public: A() : x(0) <%%> %> a;Я думаю, что вы должны сначала выучить язык, прежде чем пытаться его языковым юристом. - person T.C.   schedule 30.01.2016X x;также не указан инициализатор. Единственная разница между этим и вашим кодом в том, что я дал конструктору определение, а вы нет. - person T.C.   schedule 30.01.2016X x;, а после конструктора вctor-initializer. [class.base.init] 12.6.2 (1): в определении конструктора для класса инициализаторы для прямых и виртуальных базовых подобъектов и нестатические элементы данных может быть указан ctor-initializer. Это то, что вы сделали, и именно поэтому конструктор default не понадобился. - person apriori   schedule 30.01.2016struct A { X x; A(); } a;- в вашем случае - не вызывает конструктор по умолчаниюX(или не требует, чтобы он был). Конструктор, вызываемый дляx, полностью зависит от того, как написаноA::A(). - person T.C.   schedule 30.01.2016std::list, поэтому я принял определениеA::A() = default. Без этого предположения ваш комментарийstd::list<std::unique_ptr<B>> bs;не вызывает никакого конструктора и может быть истолкован как что-то вродеstd::list<std::unique_ptr<B>> bs;не вызывает никакого конкретного конструктора , потому что вызываемый конструктор может быть определен необязательныйctor-initializer, указанный в реализации ctor., что является правильным для IMO. - person apriori   schedule 30.01.2016