确定 (c++) 迭代器是不是是反向的
Posted
技术标签:
【中文标题】确定 (c++) 迭代器是不是是反向的【英文标题】:Determine if a (c++) iterator is reverse确定 (c++) 迭代器是否是反向的 【发布时间】:2014-03-12 18:29:55 【问题描述】:我想要一种机制来在编译时确定迭代器是否是反向的。
Iterator traits 只能帮助处理迭代器类型的 类别,而我需要的是:
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
的事实抓住。我不会/不能改变那个设计,我只是在尝试一种更优雅的方式(如果有的话)在内部处理它。我再说一遍,那是个假例子。
【问题讨论】:
reverse_iterator
怎么样? cplusplus.com/reference/iterator/reverse_iterator
@GIJoe 他知道是什么;他想知道,给定一个迭代器,是否是一个。 (不过我可能误解了你的评论。
@WhozCraig:我想这就是我的意思.. 他已经知道他需要一个 reverse_iterator。如果您传递一个 reverse_iterator 以开始,我看不出有可能接受其他任何东西
你为什么在乎?你能检查.base()
(看看它是否返回一个迭代器)吗?你所说的“是一个反向迭代器”到底是什么意思?我可以编写一个适用于所有意图的类,但std::reverse_iterator
不会返回。如何定义实现是好的?
【参考方案1】:
#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>
;
您还可以为任何用户定义的作为反向迭代器的迭代器专门化特征。
【讨论】:
太完美了,我想知道为什么它不在标准库中。我很高兴我终于问了这个问题。 因为没有人需要,所以你的函数应该是points_to_last_element(Cont const &container, It iter, It end)
并检查iter == end
,不管是不是反向迭代器
我想如果我已经结束了,那根本就没有必要了。如何从迭代器It iter
和容器Cont cont
的调用函数中获取end
迭代器?是begin()
还是rbegin()
(我将其作为评论发布,以免混淆问题)
你是如何获得iter
的?哪里来的就是你知道如何获取过去的结束迭代器的地方
那是(过去是 - 现在不再是)问题我无法在那里添加代码,我只能是该代码的用户/客户【参考方案2】:
一个简单的方法。它易于使用,并且可以确定某个东西是否是反向迭代器,并且可以根据需要区分 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;
输出:假 真 假 假
【讨论】:
以上是关于确定 (c++) 迭代器是不是是反向的的主要内容,如果未能解决你的问题,请参考以下文章