c++ 前方宣言でunique_ptrをメンバに持った場合のエラー(error: invalid application of 'sizeof' to an incomplete type 'B')


unique_ptrでコンパイルエラーが出て、調べても分からないので質問させてください。

A.h

[code]

    #include <memory>
    class B;
    
    class A {
    
        public:
            static std::unique_ptr<A> create();
    
        private:
            void init();
            std::unique_ptr<B> _b;
    
    };
    
[/code]

A.cpp

[code]

    #include "A.h"
    #include "B.h"
    std::unique_ptr<A> A::create() {
        std::unique_ptr<A> ptr(new A);
        ptr->init();
        return ptr;
    }
    
    void A::init() {
        _b = B::create();
    }
    
[/code]

B.h

[code]

    #include <memory>
    
    class B {
        public:
        static std::unique_ptr<B> create();
    };
    
[/code]

B.cpp

[code]

    #include "B.h"
    
    std::unique_ptr<B> B::create() {
            std::unique_ptr<B> ptr(new B);
            return ptr;
    }
    
[/code]

main.cpp

[code]

    #include "A.h"
    
    int main(void) {
        auto a = A::create();
        return 0;
    }
    
[/code]

以下のようなエラーが出ます

[code]

        clang++ A.cpp B.cpp main.cpp -std=c++11
        In file included from main.cpp:1:
        In file included from ./A.h:1:
        /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include/c++/v1/memory:2395:27: error: invalid application of 'sizeof' to an incomplete type 'B'
                                static_assert(sizeof(_Tp) > 0, "default_delete can not delete incomplete type");
                                                            ^~~~~~~~~~~
        /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include/c++/v1/memory:2603:13: note: in instantiation of member function 'std::__1::default_delete<B>::operator()' requested here
                                __ptr_.second()(__tmp);
                                ^
        /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include/c++/v1/memory:2571:46: note: in instantiation of member function 'std::__1::unique_ptr<B, std::__1::default_delete<B> >::reset' requested here
                _LIBCPP_INLINE_VISIBILITY ~unique_ptr() {reset();}
                                                                                                 ^
        ./A.h:4:7: note: in instantiation of member function 'std::__1::unique_ptr<B, std::__1::default_delete<B> >::~unique_ptr' requested here
        class A {
                    ^
        /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include/c++/v1/memory:2603:13: note: in instantiation of member function 'std::__1::default_delete<A>::operator()' requested here
                                __ptr_.second()(__tmp);
                                ^
        /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include/c++/v1/memory:2571:46: note: in instantiation of member function 'std::__1::unique_ptr<A, std::__1::default_delete<A> >::reset' requested here
                _LIBCPP_INLINE_VISIBILITY ~unique_ptr() {reset();}
                                                                                                 ^
        main.cpp:4:12: note: in instantiation of member function 'std::__1::unique_ptr<A, std::__1::default_delete<A> >::~unique_ptr' requested here
            auto a = A::create();
                             ^
        ./A.h:2:7: note: forward declaration of 'B'
        class B;
                    ^
        1 error generated.
    
[/code]

A.hでBの前方宣言ではなく、include B.hをすればエラーは出なくなりますが、  
こうするしかないのでしょうか？  
shared_ptrに変更した場合にはエラーは出ません。

このエラーで調べると、Pimpleに関する話題しか出なくて困っています。

よろしくお願いします。




[Pimpleに関する話題で出てくる回答](https://qiita.com/false-
git@github/items/79bf1b6acc00dc43d173#comment-9071ab88afe79f2cf834)の通り、Aのデストラクタを非インライン化すれば[コンパイルできます](https://wandbox.org/permlink/AltLgDb9coJiVD3a)。

A.h

[code]

    #include <memory>
    class B;
    
    class A {
    
        public:
            static std::unique_ptr<A> create();
            ~A(); // デストラクタを非インライン化
    
        private:
            void init();
            std::unique_ptr<B> _b;
    
    };
    
[/code]

A.cpp

[code]

    #include "A.h"
    #include "B.h"
    std::unique_ptr<A> A::create() {
        std::unique_ptr<A> ptr(new A);
        ptr->init();
        return ptr;
    }
    
    A::~A() = default; // デストラクタを非インライン化
    
    void A::init() {
        _b = B::create();
    }
    
[/code]

参考：

  * [unique_ptr はクラスの正確なサイズを知らないといけない? - Qiita](https://qiita.com/false-git@github/items/79bf1b6acc00dc43d173)

