3
template <class Data, class Allocator = std::allocator<Node> >
class Node : public Data {
  // ...
};

質問は簡単です。上記のコードをコンパイルするにはどうすればよいですか? その意図は、ノードに他のノードを割り当てる可能性を与えることです (そしてデフォルトのアロケータを提供することです)。

4

5 に答える 5

6

最後に私はそれを解決しました!解決策は、Node が既に定義されているクラスの内部まで、デフォルトのアロケーターの特殊化を遅らせることです。

template <class Data, template<class T> class TAllocator = std::allocator >
class Node : public Data {
  typedef TAllocator<Node> Allocator;
  // ...
};
于 2009-09-21T21:35:25.023 に答える
6

次のように書くことはできません。

template <class Data, class Allocator>
class Node;

template <class Data, class Allocator = 
  std::allocator<Node<Data, std::allocator<Node<...> >
class Node : public Data {
  // ...
};

デフォルトの引数はそれ自体を繰り返す必要があるためです。ただし、タグタイプを使用できます

struct DefaultAllocatorTag { };

template<typename Alloc, typename Node>
struct SelectAllocator {
  typedef Alloc type;
};

template<typename Node>
struct SelectAllocator<DefaultAllocatorTag, Node> {
  typedef std::allocator<Node> type;
};

template <class Data, class Allocator = DefaultAllocatorTag >
class Node : public Data {
  typedef typename SelectAllocator<Allocator, Node>::type 
    NodeAllocator;
};

ただし、該当する場合は、コンテナー内のアロケーターを決定します。このような:

template<typename Data, typename Allocator = std::allocator<Data> >
struct Container {
  struct Node : Data { 
    typedef typename Allocator::template rebind<Node>::other NodeAllocator;
    ...
  };
  ...
};
于 2009-09-21T20:45:26.080 に答える
2

これはどう?:

#include <memory>

template<class Data>
class NodeImpl : public Data
{
};

template<class Data, class Allocator = std::allocator< NodeImpl<Data> > >
class Node : public NodeImpl<Data>
{
};

class MyAllocator
{
};

class MyDataClass
{
};

int main()
{
    Node<MyDataClass> node;

    Node<MyDataClass, MyAllocator> node_with_alloc;

    return 0;
}
于 2009-09-21T20:52:17.717 に答える
1

コンパイルすることはできません-作成しようとしているのは「無限」タイプです。

まず、インスタンス化されていないクラス テンプレートをテンプレート引数として使用することはできません。したがって、次のように Node を std::allocator に渡す必要があります。

template <class Data, class Allocator = std::allocator<Node<Data, Something> > > 
class Node ...

しかし、それは何でしょう?さて、std::アロケータ

トリックは、アロケーターがテンプレート引数だけでなく、他の型を割り当てる必要があることです。クラスを次のように宣言します

template <class Data, class Allocator = std::allocator<Data> > class Node ...

次に、次のようにノードのアロケーターを作成します。

typename Allocator::rebind<Node>::other nodeAllocator(myDataAllocator)

アロケーターに関するこの vcblog の投稿は役立つかもしれませんが、イテレーターに重点が置かれすぎています。

于 2009-09-21T20:53:59.210 に答える
0

別の解決策。こちらの方が典型的なようです。すなわち。ベクトルとスマート ポインターの実装は、似たようなものを使用しています。アイデアは、アロケータからプライベートに継承することです:

template <class Data, template <class N> class Allocator = std::allocator>
class Node : public Data, private Allocator<Node<Data, Allocator> > {
  // ...
};

おまけに、継承宣言では既に Node.js を使用できます。

于 2009-09-22T11:46:17.690 に答える