std :: list <std :: unique_ptr>:空的初始化列表与默认构造函数

apr*_*ori 10 c++ unique-ptr c++17

代码

#include <list>
#include <memory>

class B;
class A {
    std::list<std::unique_ptr<B>> bs;
public:
    A();
    ~A();
};

int main()
{
    A x;
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

显然编译.它没有链接因为A::A()并且A::~A()缺失,但这是预期的并且没有问题.更改

std::list<std::unique_ptr<B>> bs;
Run Code Online (Sandbox Code Playgroud)

应该称之为std::list标准构造函数

list() : list(Allocator()) {}
Run Code Online (Sandbox Code Playgroud)

(C++ 14及以上)来

std::list<std::unique_ptr<B>> bs{};
Run Code Online (Sandbox Code Playgroud)

应该调用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--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,
                      ^
Run Code Online (Sandbox Code Playgroud)

关于B不完整的类型咆哮.我的问题是:

为什么initializer_list构造函数需要完整类型B的空初始化列表?

总是赞赏标准的相关部分的指针.

How*_*ant 2

我认为你已经走到了最前沿

这似乎是 CWG(C++ 委员会核心工作组)上的一个活跃问题。

CWG 1396似乎很关心这个问题。此问题链接到CWG 1360,其中部分内容如下:

类模板会加剧这个问题,因为 CWG 当前的方向是仅在需要时才实例化成员初始值设定项(请参阅问题 1396)。

在您的示例中,永远bs不需要初始化器,因此根据上面提到的“方向”,永远不应该实例化。只是今天我们还没到那一步。这两个问题都有起草状态,这意味着:他们正在处理它。

FWIW,http ://webcompiler.cloudapp.net上报告的 VS-2015编译(但当然不链接)此示例。