Подтвердить что ты не робот

Std:: list <std:: unique_ptr>: пустой список инициализаторов против конструктора по умолчанию

Код

#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{};

который должен вызывать список (std:: initializer_list, const Allocator и = Allocator()); конструктор по умолчанию. (Спасибо Николо Боласу, который справедливо упомянул [over.match.list] 13.3.1.7) дает следующую ошибку: С++ (Ubuntu 5.2.1-22ubuntu2) 5.2.1 20151010 и параметр - std = С++ 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 для пустого списка инициализаторов?

Указатели на соответствующие части стандарта всегда оценены.

4b9b3361

Ответ 1

Думаю, вы наступили на кровоточащий край.

Это, по-видимому, является активной проблемой в РГЭ (основная рабочая группа по комитету С++).

CWG 1396, похоже, касается этой самой проблемы. Эта проблема связана с CWG 1360, которая гласит:

Проблема усугубляется шаблонами классов, поскольку текущий направление CWG заключается в создании экземпляров инициализаторов элементов только тогда, когда они (см. вопрос 1396).

В вашем примере инициализатор bs никогда не нужен, и, следовательно, "направлением", о котором говорилось выше, никогда не следует создавать. Сегодня нас нет. У обоих этих вопросов есть составление статуса, то есть: они работают над ним.

FWIW, VS-2015, как сообщается в http://webcompiler.cloudapp.net, компилирует (но, конечно, не ссылается) этот пример.