If we go to the cppreference document for std::unique_ptr:
std::unique_ptrmay 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,Tmust 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_ptrcan’t be constructed from a raw pointer to incomplete
type, but can be destroyed whereTis incomplete).
We can see in the below code:
#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(){}
The requirements are not fulfilled when the defintion of STFT is commented before the destructor of Whatever is defined since this requires the destructor for stft which in turn requires STFT to be complete.
So it seems likely that in your implementation file STFT is complete when Whatever::~Whatever() is defined but otherwise the defaulted one is created without the STFT being complete.