g++ -std=c++11
不编译包含容器的类,该容器包含指向前向声明的类的唯一指针。问题:
代码示例:
#include <vector>
#include <memory>
// variant 1 (with full class definition): compiles
class Bar { [..] };
using BarPtr = std::unique_ptr<Bar>;
// variant 2 (with shared instead of unique pointers): compiles
using BarPtr = std::shared_ptr<class Bar>;
// variant 0 (which is what we want): compilation fails below
using BarPtr = std::unique_ptr<class Bar>;
// end of variants
class Foo {
std::vector<BarPtr> vec;
public:
Foo() {} // compilation of variant 0 fails here:
// In instantiation of ‘void std::default_delete<Bar>::operator()(Bar*) const
// ...
// invalid application of ‘sizeof’ to incomplete type ‘Bar’
};
我看过How to forward declare a class to be used in a standard container of unique_ptr和Is std::unique_ptr<T> required to know the full definition of T?,但没有找到令人信服的答案。
答案 0 :(得分:1)
你需要将Foo的那些部分移动到实现文件中,这需要完全定义Bar(参见Howard Hinnant的表:https://stackoverflow.com/a/6089065/2173029)。遵循本指南,编译:
#include <vector>
#include <memory>
class Bar;
using BarPtr = std::unique_ptr<Bar>;
class Foo {
std::vector<BarPtr> vec;
public:
Foo(); // Needs Bar in implementation
~Foo();// Needs Bar in implementation
};
答案 1 :(得分:0)
答案 2 :(得分:0)
问题是你不能通过指针删除不完整(前向声明)类型。确保Bar
的定义在包含类的析构函数中可见,或者为查看它的unique_ptr
使用自定义删除器。另请参阅std::unique_ptr with an incomplete type won't compile
答案 3 :(得分:0)
第
行的错误消息Foo() {};
似乎告诉我们需要析构函数~Bar()
。但为什么?我的问题的这一部分仍然是开放的。
然而,对于实际的解决方案,答案很简单:用
替换上面的行Foo();
并在编译单元中实现Foo::Foo
,该编译单元可以看到类Bar
的完整定义。