Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
668 views
in Technique[技术] by (71.8m points)

templates - Determine if a (c++) iterator is reverse

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.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)
#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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...