另一种奇怪的反复出现的模板模式

Łuk*_*Lew 3 c++ templates f-bounded-polymorphism

template <class Data, class Allocator = std::allocator<Node> >
class Node : public Data {
  // ...
};
Run Code Online (Sandbox Code Playgroud)

问题很简单,如何编译上面的代码?目的是为Node提供分配其他节点的可能性(以及提供默认分配器).

Joh*_*itb 6

不能这样写:

template <class Data, class Allocator>
class Node;

template <class Data, class Allocator = 
  std::allocator<Node<Data, std::allocator<Node<...> >
class Node : public Data {
  // ...
};
Run Code Online (Sandbox Code Playgroud)

因为默认参数必须重复.但是,您可以使用标记类型

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;
};
Run Code Online (Sandbox Code Playgroud)

如果适用,我会确定容器中的分配器.像这样:

template<typename Data, typename Allocator = std::allocator<Data> >
struct Container {
  struct Node : Data { 
    typedef typename Allocator::template rebind<Node>::other NodeAllocator;
    ...
  };
  ...
};
Run Code Online (Sandbox Code Playgroud)


Łuk*_*Lew 6

最后我解决了!解决方案是延迟默认分配器的特化,直到已经定义了Node的类的内部:

template <class Data, template<class T> class TAllocator = std::allocator >
class Node : public Data {
  typedef TAllocator<Node> Allocator;
  // ...
};
Run Code Online (Sandbox Code Playgroud)