template <class Data, class Allocator = std::allocator<Node> >
class Node : public Data {
// ...
};
问题很简单,如何让上面的代码编译?目的是让 Node 有可能分配其他节点(并提供默认分配器)。
template <class Data, class Allocator = std::allocator<Node> >
class Node : public Data {
// ...
};
问题很简单,如何让上面的代码编译?目的是让 Node 有可能分配其他节点(并提供默认分配器)。
你不能这样写:
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;
...
};
...
};
最后我解决了!解决方案是将默认分配器的特化延迟到已经定义了 Node 的类内部:
template <class Data, template<class T> class TAllocator = std::allocator >
class Node : public Data {
typedef TAllocator<Node> Allocator;
// ...
};
这个怎么样?:
#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;
}
你不能让它编译——你试图创建的是一个“无限”类型。
让我们从那开始,你不能使用未实例化的类模板作为模板参数。因此,您需要将 Node 传递给 std::allocator,如下所示:
template <class Data, class Allocator = std::allocator<Node<Data, Something> > >
class Node ...
然而,那会是什么?好吧,std::allocator
诀窍是分配器不仅需要分配它们的模板参数,还需要分配任何其他类型。宣布你的班级为
template <class Data, class Allocator = std::allocator<Data> > class Node ...
然后,为这样的节点创建分配器:
typename Allocator::rebind<Node>::other nodeAllocator(myDataAllocator)
这篇关于分配器的 vcblog 文章可能会有所帮助,尽管它过于关注迭代器。
另一种解决方案。这个好像比较典型。IE。矢量和智能指针实现使用类似的东西。这个想法是从分配器私下继承:
template <class Data, template <class N> class Allocator = std::allocator>
class Node : public Data, private Allocator<Node<Data, Allocator> > {
// ...
};
好处是在继承声明中我们已经可以使用 Node.js 了。