stl样式容器类型的特殊功能

时间:2009-12-15 02:04:19

标签: c++ templates partial-specialization

如果我有一个类型T,那么在编译时检查它是否是一种有用的方法,以查看它是否是STL样式的容器(对于任意值类型)? (假设:指针,参考等已被剥离)

开始代码:

template<class T> // (1)
void f(T&) {} 

template<class T> // (2)
void f(std::vector<T>&) {} 

void test() 
{
    int a;
    std::vector<int> b;
    f(a);
    f(b);
}

现在这个工作正常,但如果我想概括容器(即没有明确定义(3)(4),...),该怎么办?

使用SFINAE和类型列表会稍微减少代码,但是有更好的方法吗? 或者是否有基于概念的专业成语?
或者我可以以某种方式利用SFINAE选择性地只启用所需的特化吗?

作为旁注,我不能使用迭代器 - 我试图根据接收T s作为参数的函数进行专门化。


根据MSalters answer

template<class T>
void f(T&, ...) {
    std::cout << "flat" << std::endl; 
}

template<class Cont>
void f(Cont& c, typename Cont::iterator begin = Cont().begin(),
                typename Cont::iterator end   = Cont().end()) {
    std::cout << "container" << std::endl; 
}

(需要变量参数列表才能使第一个f最不受欢迎的版本来解决模糊错误)

3 个答案:

答案 0 :(得分:2)

你所做的一切几乎肯定是非常脆弱的。什么是或不是“STL”之间根本没有清晰的分界线。即使有一条清晰的分界线,在任何情况下,这种决定几乎肯定都是一个非常糟糕的基础。例如,如果我编写(或使用)std :: map的重新实现,它使用AVL树而不是更常见的R-B树,为什么它应该与std :: map区别对待?

在散列容器的情况下,从hash_map的各种实现,到Boost容器,到TR1容器,再到将包含在C ++ 0x中的标准库中的那些容器,都有一个完整的过程。根据你如何定义“STL”,有一个很好的机会,至少有一个不是STL,而另一个是STL,但是没有一点可以将一个与另一个区别对待。

我认为您应该考虑容器的特性,然后尝试确定对您来说真正重要的特征。

答案 1 :(得分:2)

根据定义,STL容器有一个typedef iterator,其中包含两个方法begin()end()。此范围容器包含的内容。如果没有这样的范围,它不是STL意义上的容器。因此,我会根据(未检查)

的内容进行调整
template<typename CONTAINER>
void f(CONTAINER& c,
       typename CONTAINER::iterator begin = c.begin(),
       typename CONTAINER::iterator end = c.end())
{ }

答案 2 :(得分:0)

根据www.cplusplus.com,所有STL容器共有的唯一函数是:

  • 构造函数
  • operator=
  • size

在编译时,您可以确定类型T上是否存在这些运算符。