5

我有

template<typename T>
class queue
{
private:
    struct node
    {
        T data;
        std::unique_ptr<node> next; //compile error on incomplete type

        node(T&& data_):
            data(std::move(data_))
        {}
    };

    std::unique_ptr<node> head;
    node* tail;

public:
        queue():
            tail(nullptr)
        {}

我在 VS10 的标记行上收到编译错误。在这种情况下,我是否应该被允许使用不完整的类型(实例化模板 - 构造函数 - 这里以 int 为例)?有解决方法吗?

编辑

singlethreadedqueue.h(62): error C2079: 'queue<T>::node::next' uses undefined class 'std::unique_ptr<_Ty>'
1>          with
1>          [
1>              T=MyClass
1>          ]
1>          and
1>          [
1>              _Ty=queue<MyClass>::node
1>          ]
1>          c:\program files\microsoft visual studio 10.0\vc\include\memory(2161) : see reference to class template instantiation 'queue<T>::node' being compiled
1>          with
1>          [
1>              T=MyClass
1>          ]
1>          c:\program files\microsoft visual studio 10.0\vc\include\memory(2195) : see reference to class template instantiation 'std::_Unique_ptr_base<_Ty,_Dx,_Empty_deleter>' being compiled
1>          with
1>          [
1>              _Ty=queue<MyClass>::node,
1>              _Dx=std::default_delete<queue<MyClass>::node>,
1>              _Empty_deleter=true
1>          ]
1>         singlethreadedqueue.h(69) : see reference to class template instantiation 'std::unique_ptr<_Ty>' being compiled
1>          with
1>          [
1>              _Ty=queue<MyClass>::node
1>          ]
1> : see reference to class template instantiation 'queue<T>' being compiled
1>          with
1>          [
1>              T=MyClass
1>          ]
4

3 回答 3

5

模板实例化点的完整类型的要求是由于std::default_delete,因此您可能可以通过提供自定义删除器来解决它。

struct node;         // node_delete need to know 'node' is a type.
struct node_deleter 
{                    // std::unique_ptr needs 'node_deleter' to be complete.
    void operator()(node* ptr);  // forward-reference to avoid needing
};                               //  'delete ptr' before the node is complete.

struct node
{
    std::unique_ptr<node, node_deleter> next;
};

void node_deleter::operator()(node* ptr)
{
     delete ptr;
}

请注意,我尚未在 MSVC 中对其进行测试,如果 VC 11 无法编译您的原始代码,您可能应该尝试升级到 VC 11,或者向 Microsoft 提交错误。

于 2012-05-03T10:59:19.627 回答
3

您的代码看起来格式正确。在构造函数体和析构函数体中,一个类被认为是一个完整的类型。

于 2012-05-02T19:34:21.277 回答
0

如果您使用shared_ptr而不是unique_ptr,则编译(在 VS2010 上)。我猜它的实现方式在 的情况下允许部分类(前向声明等)shared_ptr,但在unique_ptr. 文档boost::shared_ptr肯定说它允许这样做,但我不知道 VS2010 是否“说”了为什么他们为一个而不是另一个做这种行为。

我会说测试它,看看它是否满足您的需求shared_ptr。这不是您想要的,但如果它有效,并且速度差异不是很大,那么它可能没问题。

于 2012-05-02T20:22:43.763 回答