4

When defining the following class

class Foo 
{
public:
    Foo (void);
    ~Foo (void) = default;
protected:
    class FooImpl;
    std::unique_ptr <FooImpl> _impl;
//...
};

Foo::Foo (void) : _impl (std::make_unique <Foo> ()) {
}

I get the following error (icpc):

/home/toolworks/gcc/4.8.2/bin/../include/c++/4.8.2/bits/unique_ptr.h(65): error: incomplete type is not allowed static_assert(sizeof(_Tp)>0, ^ detected during:

instantiation of "void std::default_delete<_Tp>::operator()(_Tp *) const [with _Tp=FooImpl]" at line 184 instantiation of "std::unique_ptr<_Tp, _Dp>::~unique_ptr() [with _Tp=FooImpl, _Dp=std::default_delete]" at line 290 of "/home/toolworks/gcc/4.8.2/bin/../include/c++/4.8.2/bits/shared_ptr_base.h" instantiation of "void std::_Sp_counted_ptr<_Ptr, _Lp>::_M_dispose() [with _Ptr=Foo *, _Lp=__gnu_cxx::_S_atomic]" at line 286 of "/home/toolworks/gcc/4.8.2/bin/../include/c++/4.8.2/bits/shared_ptr_base.h" implicit generation of "std::_Sp_counted_ptr<_Ptr, _Lp>::~_Sp_counted_ptr() [with _Ptr=Foo *, _Lp=__gnu_cxx::_S_atomic]" at line 286 of "/home/toolworks/gcc/4.8.2/bin/../include/c++/4.8.2/bits/shared_ptr_base.h" instantiation of class "std::_Sp_counted_ptr<_Ptr, _Lp> [with _Ptr=Foo *, _Lp=__gnu_cxx::_S_atomic]" at line 286 of "/home/toolworks/gcc/4.8.2/bin/../include/c++/4.8.2/bits/shared_ptr_base.h" instantiation of "std::_Sp_counted_ptr<_Ptr, _Lp>::_Sp_counted_ptr(_Ptr) [with _Ptr=Foo *, _Lp=__gnu_cxx::_S_atomic]" at line 452 of "/home/toolworks/gcc/4.8.2/bin/../include/c++/4.8.2/bits/shared_ptr_base.h" instantiation of "std::__shared_count<_Lp>::__shared_count(_Ptr) [with _Lp=__gnu_cxx::_S_atomic, _Ptr=Foo *]" at line 740 of "/home/toolworks/gcc/4.8.2/bin/../include/c++/4.8.2/bits/shared_ptr_base.h" instantiation of "std::__shared_ptr<_Tp, _Lp>::__shared_ptr(_Tp1 *) [with _Tp=Foo, _Lp=__gnu_cxx::_S_atomic, _Tp1=Foo]" at line 113 of "/home/toolworks/gcc/4.8.2/bin/../include/c++/4.8.2/bits/shared_ptr.h" instantiation of "std::shared_ptr<_Tp>::shared_ptr(_Tp1 *) [with _Tp=Foo, _Tp1=Foo]" at line ... of "main.cc"

However, When I define a non-default destructor it compiles:

Foo.h

class Foo 
{
public:
    Foo (void);
    ~Foo (void);
protected:
    class FooImpl;
    std::unique_ptr <FooImpl> _impl;
//...
};

Foo.cc

Foo::~Foo (void) {

} 

it compiles. I saw at some places that said that the "=default" should compile, and it is not the same class as implicit default function (I'm new to c++11).

So, why doesn't the first Foo compiles?

Note: I' don't see how it is duplicated since I've asked about defaulted destructor, not a default destructor

Daniel Heilper
  • 1,182
  • 2
  • 17
  • 34
  • 2
    You can use `= default` to implement the destructor, however, this requires `FooImpl` to be complete. For example, in Foo.cc you can write `Foo::~Foo() = default;` after defining `FooImpl`. – dyp Apr 30 '15 at 14:15
  • @dyp I didn't know it is possible to define defaulted function in function definition, for some cases that's a great option (client shouldn't be bothered about how the method is implemented...) – Daniel Heilper Apr 30 '15 at 14:23
  • @Barry this is not exactly a duplicate, since I've asked about explicit defaulted function – Daniel Heilper Apr 30 '15 at 14:27
  • @chook It does cover this - you have to *define* the destructor elsewhere, not in the header. You're welcome to reopen if you feel that your question is insufficiently addressed. – Barry Apr 30 '15 at 14:29
  • @chook Also an explicitly defaulted destructor *is* a default destructor. – Barry Apr 30 '15 at 14:31
  • @Barry you're right that both are default, but are they generated in the same way? – Daniel Heilper Apr 30 '15 at 14:32

0 Answers0