[英]std::list<std::unique_ptr>: empty initializer list vs. default constructor
The code 代码
#include <list>
#include <memory>
class B;
class A {
std::list<std::unique_ptr<B>> bs;
public:
A();
~A();
};
int main()
{
A x;
return 0;
}
obviously compiles. 显然编译。 It doesn't link because
A::A()
and A::~A()
are missing, but that is expected and alright. 它没有链接,因为缺少
A::A()
和A::~A()
,但这是预期的并且没有问题。 Changing 更改
std::list<std::unique_ptr<B>> bs;
which is supposed to call the std::list
's standard constructor 它应该调用
std::list
的标准构造函数
list() : list(Allocator()) {}
(C++14 and up) to (C ++ 14及以上)来
std::list<std::unique_ptr<B>> bs{};
which is supposed to call list(std::initializer_list, const Allocator & = Allocator()); 应该调用
list(std :: initializer_list,const Allocator&= Allocator()); the default constructor too. 默认构造函数也是。 (Thanks to Nicol Bolas , who rightly referred to [over.match.list] 13.3.1.7) gives the following error with c++ (Ubuntu 5.2.1-22ubuntu2) 5.2.1 20151010 and the --std=c++17 parameter:
(感谢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,
^
Which barks about the type of B
being incomplete. 关于
B
类型不完整的吠叫。 My question is: 我的问题是:
Why does the initializer_list
constructor need the complete type of B
for an empty initializer list? 为什么
initializer_list
构造函数需要一个空的初始化列表的完整类型B
?
Pointers to the relevant parts of the standard are always appreciated. 总是赞赏标准的相关部分的指针。
I think you've stepped onto the bleeding edge . 我想你已经走到了前沿 。
This appears to be an active issue on the CWG (Core Working Group on the C++ committee). 这似乎是CWG(C ++委员会核心工作组)的一个活跃问题。
CWG 1396 appears to be concerned with this very issue. CWG 1396似乎关注这个问题。 This issue links to CWG 1360 which says in part:
此问题链接到CWG 1360 ,其部分内容如下:
The problem is exacerbated with class templates, since the current direction of CWG is to instantiate member initializers only when they are needed (see issue 1396).
类模板加剧了这个问题,因为CWG的当前方向是仅在需要时才实例化成员初始化器(参见问题1396)。
In your example, the initializer of bs
is never needed, and thus by the "direction" referred to above, should never be instantiated. 在示例中,初始化器
bs
被从未需要,并且因此通过上面提到的“方向”, 不应该被实例化。 We just aren't there yet today. 我们今天还不在。 Both of these issues have status drafting , meaning: they're working on it.
这两个问题都有地位起草 ,这意味着:他们正在努力。
FWIW, VS-2015 as reported at http://webcompiler.cloudapp.net compiles (but of course does not link) this example. 在http://webcompiler.cloudapp.net上报告的FWIW,VS-2015编译(但当然没有链接)这个例子。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.