I have a simple sample which provides:
a struct template:
#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; } };
a function template:
template <typename T> range_t<T> range(T b, T e) { return range_t<T>(b, e); }
I can use it to skip items in foreach loop of a (i.e) std::vector
:
int main()
{
std::vector<int> v{ 1, 2, 3, 4 };
for (auto p : range(v.begin() 1, v.end()))
{
std::cout << p << " ";
}
}
This works as intended, however I don't really understand the need of the function template (2).
I tried to write the foreach loop as this:
for (auto p : range_t<std::vector::const_iterator>(v.begin() 1, v.end()))
But for this I always got
error: template argument 1 is invalid
This might be a duplicate question, feel free to mark it as duplicate and please let me know the duplicated question which answers to all of these questions:
Why is the template argument invalid here?
(How) can I skip the function template?
How can I create a function template which would work as this:
myskipper would get only
v
as parameter in the foreach loop: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)) ...
CodePudding user response:
Based on the comments and 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;
}