Сначала вам потребуется способ , чтобы определить, является ли итератор обратным , который был изобретательно показан здесь :
#include <iterator>
#include <type_traits>
template<typename Iter>
struct is_reverse_iterator : std::false_type { };
template<typename Iter>
struct is_reverse_iterator<std::reverse_iterator<Iter>>
: std::integral_constant<bool, !is_reverse_iterator<Iter>::value>
{ };
Тогда вы можете иметь два варианта выполнения теста
template<bool isRev> // for normal iterators
struct is_last_it
{
template<typename It, typename Cont>
static bool apply(It it, Cont const &cont)
{ // you need to test with .end()
return it != cont.end() && ++it == cont.end();
}
};
template<> // for reverse iterators
struct is_last_it<true>
{
template<typename It, typename Cont>
static bool apply(It it, Cont const &cont)
{ // you need to test with .rend()
return it != cont.rend() && ++it == cont.rend();
}
};
и одну интерфейсную функцию
template<typename It, typename Cont>
bool is_last_iterator(It it, Cont const &cont)
{
return is_last_it<is_reverse_iterator<It>::value>::apply(it, cont);
};
Тогда для каждого типа итератора (обратный / прямой) вы можете использоватьинтерфейсная функция
int main()
{
std::vector<int> v;
v.push_back(1);
auto it (v.begin()), ite(v.end()); // normal iterators
auto rit(v.rbegin()), rite(v.rend()); // reverse iterators
std::cout << is_last_iterator(it, v) << std::endl;
std::cout << is_last_iterator(ite, v) << std::endl;
std::cout << is_last_iterator(rit, v) << std::endl;
std::cout << is_last_iterator(rite, v) << std::endl;
return 0;
}
Обратите внимание, что некоторые реализации (кроме достаточно распространенных std::begin()
и std::end()
, также включают std::rbegin()
и std::rend()
. По возможности используйте этот набор функций вместо члена.begin()
и т. Д.