为什么我不能手动定义模板参数?

Why can't I manually define a template parameter?

我有一个简单的示例,它提供:

  1. 结构模板:

    #include <iostream>
    #include <vector>
    
    template <typename T>
    struct range_t
    {
        T b, e;
        range_t(T x, T y) : b(x), e(y) {}
        T begin() { return b; }
        T end() { return e; }
    };
    
  2. 一个函数模板:

    template <typename T>
    range_t<T> range(T b, T e)
    {
        return range_t<T>(b, e);
    }
    

我可以用它来跳过 foreach 循环中的项目(即)std::vector:

int main()
{
    std::vector<int> v{ 1, 2, 3, 4 };

    for (auto p : range(v.begin()+1, v.end()))
    {
        std::cout << p << " ";
    }
}

这是按预期工作的,但是我不太了解 函数模板的需要 (2)。

我试着这样写 foreach 循环:

for (auto p : range_t<std::vector::const_iterator>(v.begin()+1, v.end()))

但是为此我总是得到

error: template argument 1 is invalid

这可能是一个重复的问题,请随时将其标记为重复,请让我知道回答 所有 这些问题的重复问题:

  1. 为什么模板参数在这里无效?

  2. (如何)可以跳过函数模板?

  3. 我怎样才能创建一个功能模板,它可以像这样工作:

    myskipper 只会得到 v 作为 foreach 循环中的参数:

    template<typename T>
    range_t<T::const_iterator> myskipper(T c) {
      return range_t<T::const_iterator>(c.begin()+1, c.end());
    }
    
    ...
    for (auto p : myskipper(v)) ...
    

根据评论和 this article about iterator overflow, here a complete working example

#include <iostream>
#include <vector>

template <typename T>
struct range_t
{
    T b, e;
    range_t(T x, T y) : b(x), e(y) {}
    T begin() { return b; }
    T end() { return e; }
};

template <typename T>
range_t<T> range(T b, T e)
{
    return range_t<T>(b, e);
}

template<typename T>
range_t<typename T::iterator> skip(T &c, typename T::size_type skipCount)
{
  return range_t<typename T::iterator>(c.begin() + std::min(c.size(), skipCount), c.end());
}

int main()
{
    std::vector<int> v{ 1, 2, 3, 4 };

    for (auto p : range(v.begin()+1, v.end()))
    {
        std::cout << p << " ";
    }
    
    std::cout << std::endl;
    
    for (auto p : range_t(v.begin()+1, v.end()))
    {
        std::cout << p << " ";
    }
    
    std::cout << std::endl;
    
    for (auto p : skip(v, 3))
    {
        std::cout << p << " ";
    }

    std::cout << std::endl;
}