在How do I use unique_ptr for pimpl?中受到@xtofl的鼓励,我想提出一个问题:
为什么没有用户定义的构造函数,我无法使用std::unique_ptr
实现PImpl惯用语?
考虑以下代码:
#include <memory>
class X {
public:
// X();
~X();
private:
struct Impl;
std::unique_ptr<Impl> impl_;
};
int main() {
X x;
}
g ++失败并显示以下错误
In file included from C:/MinGW64/mingw64/lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/memory:80,
from pimpl.cpp:1:
.../x86_64-w64-mingw32/8.1.0/include/c++/bits/unique_ptr.h: In instantiation of 'void std::default_delete<_Tp>::operator()(_Tp*) const [with _Tp = X::Impl]':
.../x86_64-w64-mingw32/8.1.0/include/c++/bits/unique_ptr.h:274:17: required from 'std::unique_ptr<_Tp, _Dp>::~unique_ptr() [with _Tp = X::Impl; _Dp = std::default_delete<X::Impl>]'
pimpl.cpp:3:7: required from here
.../x86_64-w64-mingw32/8.1.0/include/c++/bits/unique_ptr.h:79:16: error: invalid application of 'sizeof' to incomplete type 'X::Impl'
static_assert(sizeof(_Tp)>0,
^~~~~~~~~~~
clang失败并显示以下错误:
In file included from pimpl.cpp:1:
...\14.16.27023\include\memory:2082:21: error: invalid application of 'sizeof' to an incomplete type 'X::Impl'
static_assert(0 < sizeof (_Ty),
^~~~~~~~~~~~
...\14.16.27023\include\memory:2296:4: note: in instantiation of member function 'std::default_delete<X::Impl>::operator()' requested here
this->get_deleter()(get());
^
pimpl.cpp:3:7: note: in instantiation of member function 'std::unique_ptr<X::Impl, std::default_delete<X::Impl> >::~unique_ptr' requested here
class X {
^
pimpl.cpp:9:12: note: forward declaration of 'X::Impl'
struct Impl;
^
Visual Studio失败,出现以下错误:
pimpl.cpp
...\14.16.27023\include\memory(2082): error C2027: use of undefined type 'X::Impl'
pimpl.cpp(9): note: see declaration of 'X::Impl'
...14.16.27023\include\memory(2081): note: while compiling class template member function 'void std::default_delete<_Ty>::operator ()(_Ty *) noexcept const'
with
[
_Ty=X::Impl
]
...\14.16.27023\include\memory(2296): note: see reference to function template instantiation 'void std::default_delete<_Ty>::operator ()(_Ty *) noexcept const' being compiled
with
[
_Ty=X::Impl
]
...\14.16.27023\include\memory(2132): note: see reference to class template instantiation 'std::default_delete<_Ty>' being compiled
with
[
_Ty=X::Impl
]
...\14.16.27023\include\memory(2179): note: see reference to class template instantiation 'std::_Unique_ptr_base<_Ty,_Dx>' being compiled
with
[
_Ty=X::Impl,
_Dx=std::default_delete<X::Impl>
]
pimpl.cpp(10): note: see reference to class template instantiation 'std::unique_ptr<X::Impl,std::default_delete<_Ty>>' being compiled
with
[
_Ty=X::Impl
]
...\14.16.27023\include\memory(2082): error C2338: can't delete an incomplete type
...\14.16.27023\include\memory(2084): warning C4150: deletion of pointer to incomplete type 'X::Impl'; no destructor called
pimpl.cpp(9): note: see declaration of 'X::Impl'