繁体   English   中英

确定(c ++)迭代器是否反向

[英]Determine if a (c++) iterator is reverse

我想要一种在编译时确定迭代器是否反向的机制。

迭代器特征只能帮助解决迭代器类型的类别 ,而我需要的是以下内容:

template<typename IterType>
struct IsReverseIterator
{
    enum { Yes = /* Implementation of the mechanism */ };
}

我有一个解决方案,尽管它有一个小的缺点,但是还必须提供容器类型:

typedef char     TrueT;
typedef struct { TrueT _[2]; } FalseT;

template<typename Cont> TrueT  IsReverseIterator(typename Cont::const_reverse_iterator);    
template<typename Cont> FalseT IsReverseIterator(...);

它显然使用了SFINAE,可以这样使用:

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;    

有任何想法吗?

编辑

为了说明我要搜索的内容,例如以下代码

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();
}

这是一个虚拟的示例,请不要被我已经处理过的代码或者我可能会有两个重载,一个带有Cont::reverse_iterator而另一个带有Cont::iterator的事实所Cont::reverse_iterator 我不会/无法更改该设计,我只是在尝试一种更优雅的方法(如果有)在内部进行处理。 我再次重申那是一个虚拟的例子。

#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>
{ };

您还可以为所有作为反向迭代器的用户定义迭代器特化特征。

一种简单的方法。 它易于使用,可以确定某项是否为反向迭代器,并且可以根据需要在const反向迭代器之间进行区分。

#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;

}

输出:

真正

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM