Why is "error: invalid application of 'sizeof' to an incomplete type using unique_ptr" fixed by adding an empty destructor?
Why is "error: invalid application of 'sizeof' to an incomplete type using unique_ptr" fixed by adding an empty destructor?
我正在 class STFT
上拉皮条。在 header:
中用这个编译就好了
class STFT; // pimpl off to prevent point name clash
class Whatever
{
private:
STFT* stft;
这在实现中:
#include "STFT.h"
Whatever::Whatever() : stft(new STFT()) {
// blah blah
}
Whatever::~Whatever() {
delete stft; // pure evil
}
但是,在 header 中的原始指针上切换到 std::unique_ptr<STFT> stft;
并删除析构函数,我得到
error: invalid application of 'sizeof' to an incomplete type 'STFT'
static_assert(sizeof(_Tp) > 0, "default_delete can not delete incomplete type");
但是,如果我只是提供一个空的析构函数 Whatever::~Whatever(){}
,那么它可以正常编译。这让我完全难住了。请告诉我这个无意义的析构函数为我做了什么。
如果我们转到 std::unique_ptr
的 cppreference 文档:
std::unique_ptr
may be constructed for an incomplete type T
, such as
to facilitate the use as a handle in the Pimpl idiom. If the default
deleter is used, T
must be complete at the point in code where the
deleter is invoked, which happens in the destructor, move assignment
operator, and reset member function of std::unique_ptr
. (Conversely,
std::shared_ptr
can't be constructed from a raw pointer to incomplete
type, but can be destroyed where T
is incomplete).
我们可以在下面的代码中看到:
#include <memory>
class STFT; // pimpl off to prevent point name clash
class Whatever
{
public:
~Whatever() ;
private:
std::unique_ptr<STFT> stft;
} ;
//class STFT{};
Whatever::~Whatever() {}
int main(){}
如果在定义 Whatever
的析构函数之前注释 STFT
的定义,则不满足要求,因为这需要 stft
的析构函数,而 stft
又需要 STFT
完成。
因此,在您的 实现 文件中, STFT
似乎很可能在定义 Whatever::~Whatever()
时完成,否则默认创建的文件没有 STFT
完成。
我提供此类析构函数的惯用语是(在实现文件中):
#include "STFT.h"
Whatever::~Whatever() = default;
重要的是它需要位于指向类型完整的地方。
我正在 class STFT
上拉皮条。在 header:
class STFT; // pimpl off to prevent point name clash
class Whatever
{
private:
STFT* stft;
这在实现中:
#include "STFT.h"
Whatever::Whatever() : stft(new STFT()) {
// blah blah
}
Whatever::~Whatever() {
delete stft; // pure evil
}
但是,在 header 中的原始指针上切换到 std::unique_ptr<STFT> stft;
并删除析构函数,我得到
error: invalid application of 'sizeof' to an incomplete type 'STFT' static_assert(sizeof(_Tp) > 0, "default_delete can not delete incomplete type");
但是,如果我只是提供一个空的析构函数 Whatever::~Whatever(){}
,那么它可以正常编译。这让我完全难住了。请告诉我这个无意义的析构函数为我做了什么。
如果我们转到 std::unique_ptr
的 cppreference 文档:
std::unique_ptr
may be constructed for an incomplete typeT
, such as to facilitate the use as a handle in the Pimpl idiom. If the default deleter is used,T
must be complete at the point in code where the deleter is invoked, which happens in the destructor, move assignment operator, and reset member function ofstd::unique_ptr
. (Conversely,std::shared_ptr
can't be constructed from a raw pointer to incomplete type, but can be destroyed whereT
is incomplete).
我们可以在下面的代码中看到:
#include <memory>
class STFT; // pimpl off to prevent point name clash
class Whatever
{
public:
~Whatever() ;
private:
std::unique_ptr<STFT> stft;
} ;
//class STFT{};
Whatever::~Whatever() {}
int main(){}
如果在定义 Whatever
的析构函数之前注释 STFT
的定义,则不满足要求,因为这需要 stft
的析构函数,而 stft
又需要 STFT
完成。
因此,在您的 实现 文件中, STFT
似乎很可能在定义 Whatever::~Whatever()
时完成,否则默认创建的文件没有 STFT
完成。
我提供此类析构函数的惯用语是(在实现文件中):
#include "STFT.h"
Whatever::~Whatever() = default;
重要的是它需要位于指向类型完整的地方。