C ++ 11容器的前向声明类的unique_ptr

时间:2016-01-06 07:35:29

标签: c++ c++11 unique-ptr forward-declaration

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_ptrIs std::unique_ptr<T> required to know the full definition of T?,但没有找到令人信服的答案。

4 个答案:

答案 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)

你可以这样做:

fullname

Live Demo

答案 2 :(得分:0)

问题是你不能通过指针删除不完整(前向声明)类型。确保Bar的定义在包含类的析构函数中可见,或者为查看它的unique_ptr使用自定义删除器。另请参阅std::unique_ptr with an incomplete type won't compile

答案 3 :(得分:0)

行的错误消息
Foo() {};

似乎告诉我们需要析构函数~Bar()。但为什么?我的问题的这一部分仍然是开放的。

然而,对于实际的解决方案,答案很简单:用

替换上面的行
Foo();

并在编译单元中实现Foo::Foo,该编译单元可以看到类Bar的完整定义。

相关问题