Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Possible bug in unique_ptr implementation [duplicate]

I was trying to use unique_ptr class member with forward declaration. As numerous sources says e.g. Forward declaration with unique_ptr? it should be sufficient to declare non inline destructor, but it seems not to be a case in VS2013 and GCC 5.3.1. I didn't test other compilers.

Example:

#include <memory>

class B;

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

//class B { };

int main() {
    A a;
}

I can make this code compile only after uncommenting the ctor declaration or the class B declaration. Otherwise on VS2013 I get error

error C2338: can't delete an incomplete type

on GCC error:

In file included from /usr/local/include/c++/5.3.0/memory:81:0,
                 from main.cpp:1:
/usr/local/include/c++/5.3.0/bits/unique_ptr.h: In instantiation of 'void std::default_delete<_Tp>::operator()(_Tp*) const [with _Tp = B]':
/usr/local/include/c++/5.3.0/bits/unique_ptr.h:236:17:   required from 'std::unique_ptr<_Tp, _Dp>::~unique_ptr() [with _Tp = B; _Dp = std::default_delete<B>]'
main.cpp:5:7:   required from here
/usr/local/include/c++/5.3.0/bits/unique_ptr.h:74:22: error: invalid application of 'sizeof' to incomplete type 'B'
  static_assert(sizeof(_Tp)>0,
                      ^

Why is this?

like image 972
pdondziak Avatar asked Mar 16 '16 13:03

pdondziak


People also ask

Can we copy unique_ptr?

A unique_ptr does not share its pointer. It cannot be copied to another unique_ptr , passed by value to a function, or used in any C++ Standard Library algorithm that requires copies to be made. A unique_ptr can only be moved.

What is a std:: unique_ ptr?

std::unique_ptr is a smart pointer that owns and manages another object through a pointer and disposes of that object when the unique_ptr goes out of scope. The object is disposed of, using the associated deleter when either of the following happens: the managing unique_ptr object is destroyed.


1 Answers

The destructor of class A must know the definition of class B. A forward declaration of class B is okay as longs as the implementation file of the constructor/destructor of A knows the definition of class B. If your implementation is (implicitly) in a header file then you need a definition of B in your header file. You may study Pimpl from Herb Sutter.

like image 129
knivil Avatar answered Oct 16 '22 09:10

knivil