I want a mechanism to determine in compile time whether an iterator is reverse or not.
Iterator traits can only help with the category of an iterator type and what I need is something in the lines of:
template<typename IterType>
struct IsReverseIterator
{
enum { Yes = /* Implementation of the mechanism */ };
}
I have a solution, that has a small drawback though, the container type has to be provided as well :
typedef char TrueT;
typedef struct { TrueT _[2]; } FalseT;
template<typename Cont> TrueT IsReverseIterator(typename Cont::const_reverse_iterator);
template<typename Cont> FalseT IsReverseIterator(...);
It uses SFINAE obviously and can be utilized like so :
std::vector<int> v;
std::cout << (sizeof(IsReverseIterator<std::vector<int>>(v.begin())) == sizeof(TrueT)) << std::endl;
std::cout << (sizeof(IsReverseIterator<std::vector<int>>(v.rbegin())) == sizeof(TrueT)) << std::endl;
Any ideas?
EDIT
To explain what I'm searching for, take for example the following code
template<typename Cont, typename It>
bool points_to_last_element(Cont const &container, It iter)
{
return iter == container.rend();
// here I would like to dispatch to 2 implementations
// one for reverse iterators and one for forward where this would happen
// return iter == container.end();
}
It is a dummy example, please don't get caught on the fact that the code I have already handles it or that I could have two overloads, one taking Cont::reverse_iterator
and one taking Cont::iterator
. I don't/can't change that design, I'm just trying a more elegant way (if there's any) to handle it internally. Again I repeat that was a dummy example.
#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>
{ };
You could also specialize the trait for any user-defined iterators that are reverse iterators.
A simple method. It is easy to use and can determine if something is a reverse iterator or not, and can differentiate between const reverse iterators if needed.
#include <iostream>
template<typename Container, typename T>
using IsRegRevIter = std::is_same<T,typename Container::reverse_iterator>;
template<typename Container, typename T>
using IsConstRevIter = std::is_same<T,typename Container::const_reverse_iterator>;
template<typename Container, typename T>
struct IsRevIter
{
const static bool value = IsRegRevIter<Container,T>::value
|| IsConstRevIter<Container,T>::value;
};
int main()
{
using Container = std::list<int>;
Container myList = {1,2,3,4,5,6};
auto RI = myList.rbegin();
auto I = myList.begin();
std::cout << std::endl << std::boolalpha << IsRevIter<Container,decltype(RI)>::value; //true
std::cout << std::endl << std::boolalpha << IsRegRevIter<Container,decltype(RI)>::value; //true
std::cout << std::endl << std::boolalpha << IsConstRevIter<Container,decltype(RI)>::value; //false (it is not const).
std::cout << std::endl << std::boolalpha << IsRevIter<Container,decltype(I)>::value; //false
return 0;
}
output:
false
true
false
false
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.