2010-02-10 87 views
2

我有一个类看起来像这样:C++模板类

#include <vector> 
#include "record.h" 
#include "sortcalls.h" 

template< 
    typename T, 
    template<typename , typename Allocator = std::allocator<T> > class Cont = std::vector> 
class Sort: public SortCall { 

此代码工作,我打电话像这样从其他类:

Comparator c; // comparison functor 
Sort< Record, std::vector > s(c); 

现在我希望能够将容器切换到另一个容器,比如列表。 所以我认为typedef会很整齐。它应该是这样的

typedef std::vector<Record> container; // Default record container 

template< 
    typename T, 
    template< typename, typename container > // ??? 
class Sort: public SortCall { 
+1

我不确定我是否理解;你没有在任何地方使用'排序'。另外,'_Alloc'保留给编译器;你应该改变它为'Allocator'或者其他东西。 – GManNickG 2010-02-10 21:54:28

+1

我不确定我明白为什么模板参数必须这么复杂。为什么不用'template class Sort ...'用'Sort s''? – UncleBens 2010-02-10 22:05:06

+0

@GMan thx。改变了它。 – mre 2010-02-10 22:06:49

回答

5

不要使用模板模板参数(在你的代码),他们是脆弱和不灵活。使用绑定机制,如果你需要(标准::分配器就是一个例子),但在这种情况下,不要:

template<class T, class Cont=std::vector<T> > 
struct Sort { 
    typedef Cont container_type; // if you need to access it from outside the class 
    // similar to std::vector::value_type (which you might want to add here too) 
}; 

typedef Sort<int, std::list<int> > IntListSort; 

比较到std ::队列和std ::栈,这也遵循这一模式。

+0

在模板模板参数中使用这种设计是我们很多人难以了解的事情之一,其中很多人眯着眼睛看着标准和头部的划痕。 +1。 – 2010-02-10 22:19:08

+0

这可能是未来发展的最佳解决方案。你得到我的投票。虽然UncleBens提供了第一个工作解决方案。 Thx所有! – mre 2010-02-10 22:34:23

0

你应该能够在typename后面直接使用'container',就像你在你的例子中那样。编译器运行时,它的类型规范会被扩展。

尝试编译它...

0

我想,如果你使用型特征可能更容易。 STL和boost中的每个容器都有数字off typedef,其中value_type(请参阅参考文献http://www.cplusplus.com/reference/stl/vector/)。 所以,你的代码可能看起来像:

template<class C> 
class sort { 
    typedef typename C::value_type value_type; // equivalent to T in your case. 
    // similarly you can get allocator, iterator, etc.