mercredi 3 octobre 2018

Creating shared_ptr of a class containing a unique_ptr to a forwarded type fails

This code

#include <memory>

class A {
public:
  class B;
  std::unique_ptr<B> b;
  A();
};

void foo() {
  std::make_shared<A>();
}

Fails with:

In file included from /usr/include/c++/7/memory:80:0,
                 from aaa.cpp:1:
/usr/include/c++/7/bits/unique_ptr.h: In instantiation of ‘void std::default_delete<_Tp>::operator()(_Tp*) const [with _Tp = A::B]’:
/usr/include/c++/7/bits/unique_ptr.h:268:17:   required from ‘std::unique_ptr<_Tp, _Dp>::~unique_ptr() [with _Tp = A::B; _Dp = std::default_delete<A::B>]’
aaa.cpp:3:7:   required from ‘void __gnu_cxx::new_allocator<_Tp>::destroy(_Up*) [with _Up = A; _Tp = A]’
/usr/include/c++/7/bits/alloc_traits.h:487:4:   required from ‘static void std::allocator_traits<std::allocator<_Tp1> >::destroy(std::allocator_traits<std::allocator<_Tp1> >::allocator_type&, _Up*) [with _Up = A; _Tp = A; std::allocator_traits<std::allocator<_Tp1> >::allocator_type = std::allocator<A>]’
/usr/include/c++/7/bits/shared_ptr_base.h:535:35:   required from ‘void std::_Sp_counted_ptr_inplace<_Tp, _Alloc, _Lp>::_M_dispose() [with _Tp = A; _Alloc = std::allocator<A>; __gnu_cxx::_Lock_policy _Lp = (__gnu_cxx::_Lock_policy)2]’
aaa.cpp:12:1:   required from here
/usr/include/c++/7/bits/unique_ptr.h:76:22: error: invalid application of ‘sizeof’ to incomplete type ‘A::B’
  static_assert(sizeof(_Tp)>0,

It seems the compiler tries to define a default delete to the A::B type that is forward declared.

Can somebody explain why make_shared needs to know the default delete? And how to overcome that?

Aucun commentaire:

Enregistrer un commentaire