不完整的类型的应用无效。
请首先查看目录结构[问题结束的底部]。
以下是我的cmake文件:
主cmake
cmake_minimum_required(版本3.9) set(cmake_cxx_standard 14) add_executable(test main.cc) target_include_directories(测试public test_include_interface) target_link_libraries(测试public test_test)
测试CMAKE:
add_library(test_include_interface接口) target_include_directories(test_include_interface接口$ {cmake_current_source_dir}) add_library(test_test static test_interface.h test.h test.cc) target_include_directories(test_test接口$ {cmake_current_source_dir})
test.h
#pragma once
#include "test_interface.h"
#include <memory>
class Test : public ITest {
public:
Test();
private:
class Impl;
std::unique_ptr<Impl> impl_;
};
test.cc
#include "test.h"
class Test::Impl {
public:
Impl() {}
~Impl() {}
};
Test::Test() : impl_{std::make_unique<Impl>()} {}
错误:
In file included from /usr/include/c++/9/memory:80,
from /home/vkd0726/test/test/test.h:9,
from /home/vkd0726/test/main.cc:2:
/usr/include/c++/9/bits/unique_ptr.h: In instantiation of ‘void std::default_delete<_Tp>::operator()(_Tp*) const [with _Tp = Test::Impl]’:
/usr/include/c++/9/bits/unique_ptr.h:292:17: required from ‘std::unique_ptr<_Tp, _Dp>::~unique_ptr() [with _Tp = Test::Impl; _Dp = std::default_delete<Test::Impl>]’
test/test/test.h:11:7: required from here
/usr/include/c++/9/bits/unique_ptr.h:79:16: error: invalid application of ‘sizeof’ to incomplete type ‘Test::Impl’
79 | static_assert(sizeof(_Tp)>0,
| ^~~~~~~~~~~
make[2]: *** [CMakeFiles/test.dir/build.make:63: CMakeFiles/test.dir/main.cc.o] Error 1
make[1]: *** [CMakeFiles/Makefile2:76: CMakeFiles/test.dir/all] Error 2
make: *** [Makefile:84: all] Error 2
请帮助我了解此错误以及如何解决该错误? CMAKE或代码本身是一个问题。我已经在许多地方看到了这种“ IMPH”设计模式使用,但无法编写测试片段。这里怎么了?
目录结构
Please have a look at directory structure first [ attached at the bottom of the question end].
Following are my Cmake files :
Main cmake
cmake_minimum_required(VERSION 3.9) set (CMAKE_CXX_STANDARD 14) add_executable (test main.cc) target_include_directories(test PUBLIC test_include_interface) target_link_libraries(test PUBLIC test_test)
Test cmake :
add_library(test_include_interface INTERFACE) target_include_directories(test_include_interface INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}) add_library(test_test STATIC test_interface.h test.h test.cc) target_include_directories(test_test INTERFACE ${CMAKE_CURRENT_SOURCE_DIR})
test.h
#pragma once
#include "test_interface.h"
#include <memory>
class Test : public ITest {
public:
Test();
private:
class Impl;
std::unique_ptr<Impl> impl_;
};
test.cc
#include "test.h"
class Test::Impl {
public:
Impl() {}
~Impl() {}
};
Test::Test() : impl_{std::make_unique<Impl>()} {}
Error :
In file included from /usr/include/c++/9/memory:80,
from /home/vkd0726/test/test/test.h:9,
from /home/vkd0726/test/main.cc:2:
/usr/include/c++/9/bits/unique_ptr.h: In instantiation of ‘void std::default_delete<_Tp>::operator()(_Tp*) const [with _Tp = Test::Impl]’:
/usr/include/c++/9/bits/unique_ptr.h:292:17: required from ‘std::unique_ptr<_Tp, _Dp>::~unique_ptr() [with _Tp = Test::Impl; _Dp = std::default_delete<Test::Impl>]’
test/test/test.h:11:7: required from here
/usr/include/c++/9/bits/unique_ptr.h:79:16: error: invalid application of ‘sizeof’ to incomplete type ‘Test::Impl’
79 | static_assert(sizeof(_Tp)>0,
| ^~~~~~~~~~~
make[2]: *** [CMakeFiles/test.dir/build.make:63: CMakeFiles/test.dir/main.cc.o] Error 1
make[1]: *** [CMakeFiles/Makefile2:76: CMakeFiles/test.dir/all] Error 2
make: *** [Makefile:84: all] Error 2
Please help me understand this error and how to resolve it ? Is it a problem with the Cmake or code itself. I have seen such "Impl" design pattern use at many places but unable to write a test snippet. What is wrong here ?
Directory structure
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
test
不包含用户定义的破坏者,因此编译器会生成此驱动器的隐藏版本。由于该驱动器涉及逻辑以删除test :: impl
对象当std :: simory_ptr&lt; test :: strime_ptr&test :: strand&gt;
被调用时,您会收到编译器的错误抱怨。您可以通过在
test.cc
中定义驱动器来解决此问题:test.h
test.cc
The
Test
does not contain a user defined destructor, so the compiler generates a inlined version of this destructor. Since this destructor involves logic to delete theTest::Impl
object when the destructor ofstd::unique_ptr<Test::Impl>
is invoked, you get the error your compiler complains about.You can fix this by defining the destructor in
test.cc
:test.h
test.cc
这是一个常见的问题,与
std :: simel_ptr
for pimpl 。正如@fabian提到的主要方法是提供声明FIR嵌套类的驱动器,并在与 pimpl 实现的同一翻译单元中定义它(最有可能是默认函数)。但是,由于编译器无法推断出嵌套类的损坏器的微不足道(根据OP,test
),这种方法可能会禁用某些角案例的优化。另一种方法是为std :: simolor_ptr
提供A deleter 类,然后将嵌套类的destructor完好无损:现在在相同的翻译中定义Deleter的函数调用操作员单位为Ingl:
这看起来还有更多的工作。但是它以隐式定义的驱动器有效。它还更好地适合0/3/5的规则。
This is a common problem faced with
std::unique_ptr
for pimpl. The primary approach would be - as @fabian mentioned - to provide a declaration fir the nesting class's destructor and define it in the same translation unit as the pimpl implementation (most probably as a defaulted function). But this approach might disable some corner case optimizations, due to compiler not being able to deduce the triviality of the destructor of nesting class(Test
according to OP). Another approach would be to provide a deleter class for thestd::unique_ptr
and leave the nesting class`s destructor intact:Now define the deleter's function call operator in the same translation unit as impl to:
This looks a little more work. But it pays off with an implicitly defined destructor. It also better suits the rule of 0/3/5.