2

我正在尝试编写一个简单的“跳过迭代器”,其中包含要跳过的元素数量的模板参数:

template <typename T, typename Iter, int Skip>
class SkipIterator
{
public:
    SkipIterator(Iter baseIter) :
        baseIter_(baseIter)
    {
    }

    void operator++()
    {
        baseIter_ += Skip;
    }

    T &operator*()
    {
        return *baseIter_;
    }

private:
    Iter baseIter_;
};

我希望能够推断出这样的基数IterT类型:

std::vector<double> dataFromSomewhere;
SkipIterator<3> skipper(dataFromSomewhere.begin())

但是编译器(VS2010)给出了“模板参数太少”的错误。

有没有办法做到这一点?

4

2 回答 2

8

您可以提供一个辅助函数:

#include <iterator>

template <int Skip, typename Iter>
SkipIterator<typename std::iterator_traits<Iter>::value_type, Iter, Skip> 
    make_skip_iterator(Iter it)
{
    return SkipIterator<
        typename std::iterator_traits<Iter>::value_type, Iter, Skip
        >(it);
}

你会用这种方式:

std::vector<double> dataFromSomewhere;
auto skipper = make_skip_iterator<3>(dataFromSomewhere.begin());

这是一个活生生的例子

请注意,由于返回类型推导,上述辅助函数的 C++14 版本看起来会更好(至少在签名中):

template <int Skip, typename Iter>
auto make_skip_iterator(Iter it)
{
    return SkipIterator<
        typename std::iterator_traits<Iter>::value_type, Iter, Skip
        >(it);
}

当然还有活生生的例子

于 2013-07-15T22:02:17.030 回答
6

模板参数推导只发生在模板函数调用中,绝不发生在涉及类模板名称的变量声明中。另外,如果你想推导出一些但不是所有的参数,你想推导的参数必须在最后。

总而言之,您正在寻找这样的东西:

template <int Skip, typename Iter>
auto make_skipper(Iter it)->SkptIterator<decltype(*it), Iter, Skip> {
  return SkptIterator<decltype(*it), Iter, Skip>(it);
}

auto skipper = make_skipper<3>(dataFromSomewhere.begin());
于 2013-07-15T22:02:42.750 回答