C++ 专门化stl样式容器类型上的函数
如果我有一个类型C++ 专门化stl样式容器类型上的函数,c++,templates,partial-specialization,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;
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);
}
(需要变量参数列表,使第一个f
成为解决歧义错误的最不首选版本)根据,所有STL容器通用的唯一功能是:
- 构造器
operator=
大小
在编译时,您可以确定这些运算符是否存在于您的类型
T
上。您所做的任何事情都几乎肯定是非常脆弱的。在什么是“STL”和什么不是“STL”之间根本没有明确的分界线。即使有一条清晰的分界线,在任何情况下,这几乎肯定都是一个非常糟糕的决定基础。举个例子,如果我编写(或使用)std::map的重新实现,它使用AVL树而不是更常见的R-B树,那么为什么要将其与std::map区别对待呢
在散列容器的情况下,从Hash映射的各种实现到升压容器、Tr1容器、到将包含在C++ 0x中的标准库中的所有进程都有一个整体的进展。根据你对“STL”的定义,很有可能其中至少有一个不是STL,另一个是STL,但在任何一点上,区别对待一个和另一个都是没有意义的
我认为您应该考虑容器的特性,然后尝试确定对您真正重要的特性。stl容器根据定义有一个typedef
迭代器,有两个方法begin()
和end()
重新运行它们。此范围是容器包含的范围。如果没有这样的范围,它就不是STL意义上的容器。因此,我建议按照(未检查)的路线做一些事情
模板
空f(集装箱和集装箱),
typename容器::迭代器begin=c.begin(),
typename容器::迭代器end=c.end()
{ }
你能举一个你想做的专门化的例子吗?我试过了,希望能让大家明白。几乎:P你能重命名f
以匹配函数的功能吗?所以你想让第二个不只是转换x
,而是现在转换并插入x
的所有元素,斯菲娜通常不会踢吗?如果t
不能back\u插入
或x
在
处没有,则将使用第一个。我曾想过这样做,但对我来说这似乎是一个黑客攻击,可能太容易破坏。我没有尝试隔离stl容器,因此使用了“stl样式”,但是我不知道如何根据这些特点来专门化。@gf:你为什么专门研究“stl风格”?“stl样式”和“非stl样式”的区别是什么?我的意思是支持stl样式的操作。这个想法(可能有些过分)不仅专门针对某些容器,而且允许使用支持stl样式的back insertion.MSalters等的anly容器,这是默认参数的一个优点,谢谢。不过它仍然存在问题,我将更新这个问题。Chip,位集
与容器的大多数行为不符,所以我会将其计算出来。
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;
}
template<typename CONTAINER>
void f(CONTAINER& c,
typename CONTAINER::iterator begin = c.begin(),
typename CONTAINER::iterator end = c.end())
{ }