![](/img/trans.png)
[英]Specializing STL algorithms so they automatically call efficient container member functions when available
[英]specializing functions on stl style container types
如果我有一个类型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的回答 :
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
成为解决歧义错误的最不优选版本)
你所做的一切几乎肯定是非常脆弱的。 什么是或不是“STL”之间根本没有清晰的分界线。 即使有一条清晰的分界线,在任何情况下,这种决定几乎肯定都是一个非常糟糕的基础。 例如,如果我编写(或使用)std :: map的重新实现,它使用AVL树而不是更常见的RB树,为什么它应该与std :: map区别对待?
在散列容器的情况下,从hash_map的各种实现,到Boost容器,到TR1容器,再到将包含在C ++ 0x中的标准库中的那些容器,都有一个完整的过程。 根据你如何定义“STL”,很有可能其中至少有一个不是STL而另一个是STL,但是没有一点可以将一个与另一个区别对待。
我认为您应该考虑容器的特性 ,然后尝试确定对您来说真正重要的特征。
根据定义,STLcontainer有一个typedef iterator
,有两个方法begin()
和end()
返回它们。 该范围是容器包含的范围。 如果没有这样的范围,它不是STL意义上的容器。 所以我会沿着(不检查)的方向发一些东西
template<typename CONTAINER>
void f(CONTAINER& c,
typename CONTAINER::iterator begin = c.begin(),
typename CONTAINER::iterator end = c.end())
{ }
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.