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 に答える