为通用函数定义自定义迭代器特征

时间:2014-07-16 21:00:01

标签: c++ templates generic-programming

我试图编写一个泛型函数,它将根据给定的迭代器在编译时派生一个返回类型。通常这是通过std :: iterator_traits完成的,但我也想定义我自己的iterator_traits版本,称为my_iterator traits。这是我的代码:

#include <cassert>
#include <iterator>
#include <vector>

using namespace std;

template <typename I>
struct my_iterator_traits {
    typedef typename I::value_type                     value_type;
    typedef typename I::iterator_category       iterator_category;
};

template <typename T>
struct my_iterator_traits<T*> {
    typedef T                                         value_type;
    typedef std::random_access_iterator_tag    iterator_category;
};                                                               

template <typename II>
typename my_iterator_traits<II>::value_type f(II b, II e) {
    typename my_iterator_traits<II>::value_type val = 0;
    return val;
}

int main () {
    int a[] = {2, 3, 4};
    int i = f(a, a + 3);

    assert(i == 0);

    // vector<int> v = {2};
    // f(v.begin(), v.end());

    // assert(j == 0);
    return 0;
}

包括main函数和函数f()在内的所有内容都非常有意义。在main中,我创建一个int数组,在其上调用f(),并确认我得到的输出是一个值为零的int。

以下内容并不清楚。我在顶部有两个模板,后跟struct关键字。使用第二个(以T*作为模板参数的那个)是完全合理的。具体来说,为什么我们需要第一个结构模板(没有模板参数的模板)?更重要的是,两个结构模板之间的关系是什么?

2 个答案:

答案 0 :(得分:0)

第一个是模板的声明,第二个是第一个的partial specialization。如链接中所解释的部分特化可以定制模板参数(例如:一些固定参数,对您所引用的参数(指针,引用等等)的某些限制等)。

答案 1 :(得分:0)

第一个template<typename>structtemplate,第二个是第一个template的特化。

template特化与类似于覆盖(但不是真的)类似于基于模式匹配的东西。如果template的参数可以通过专门化模式进行匹配,则可以使用它。

此模式匹配不会以与函数覆盖相同的方式进行类型转换。然而,SFINAE正在进行高级工作。