C ++部分模板专业化:如何专门化std :: iterator_category

时间:2013-11-26 00:42:46

标签: c++ template-specialization partial-specialization

我想编写模板函数void foo(),它需要2个迭代器或指针。

我想拥有random_access_iterator的专用版本。我试着写下面的内容:

// generic version
template<class Iter, typename std::iterator_traits<Iter>::iterator_category>
void foo(Iter first, Iter last);

// Specialized version for random_access_iterator
template<class RandomIter>
void foo<RandomIter, std::random_access_iterator_tag>(RandomIter first, RandomIter last)
{
}

它给出错误:非法使用显式模板参数

请让我知道定义此内容的正确方法。感谢

2 个答案:

答案 0 :(得分:3)

您不能部分专门化功能模板。部分特化仅适用于类模板。你可以做的是只有一个功能模板,它委托给适当专业的类模板的static成员,例如

template <typename Iter,
          typename = typename std::iterator_traits<Iter>::iterator_category>
struct foo_impl {
    static void call(Iter first, Iter last);
};

template <typename Iter>
struct foo_impl<Iter, std::random_acces_iterator_tag> {
    static void call(Iter first, Iter last);
};

templlate <typename Iter>
void foo(Iter first, last) {
    foo_impl<Iter>::call(first, last);
}

或者您可以使用部分排序。在这种情况下,有两个函数模板,一个采用一般迭代器类别作为参数,另一个采用特定类别作为参数。类别或指向它的指针作为附加参数传递。我认为这也需要转发功能(我通常使用类模板的部分特化方法)。

答案 1 :(得分:2)

基于“标签调度”模式,我已经为我的问题编写了一个解决方案:

// Using "= delete" on un-supported categories to get concise compile-time error information
template<typename Iter> void _foo(Iter first, Iter last, std::bidirectional_iterator_tag) = delete;

template<typename RandomIter>
void _foo(RandomIter first, RandomIter last, std::random_access_iterator_tag)
{ ... }

template<class Iter>
void foo(Iter first, Iter last)
{
    typename std::iterator_traits<Iter>::iterator_category category;
    _foo(first, last, category);
}

现在有效。如果有错误或需要改进,请留下评论。感谢。