【发布时间】:2019-02-25 00:23:51
【问题描述】:
我天真地期望这个程序能够以成功的状态编译和运行:
#include <iterator>
#include <string>
int main()
{
const std::string s = "foo";
auto forward_iter = s.begin();
auto reverse_iter = std::make_reverse_iterator(forward_iter);
auto third_iter = std::make_reverse_iterator(reverse_iter);
return forward_iter != third_iter;
}
编译失败,因为third_iter的类型和我们开始的forward_iter的类型不一样;相反,它是reverse_iterator<reverse_iterator<normal_iterator>>:
0.cpp:10:25: error: no match for ‘operator!=’ (operand types are ‘__gnu_cxx::__normal_iterator<const char*, std::__cxx11::basic_string<char> >’ and ‘std::reverse_iterator<std::reverse_iterator<__gnu_cxx::__normal_iterator<const char*, std::__cxx11::basic_string<char> > > >’)
return forward_iter != third_iter;
~~~~~~~~~~~~~^~~~~~~~~~~~~
重新阅读文档,似乎std::make_reverse_iterator(it) 被指定为始终包装it,即使it 已经是一个反向迭代器(在某种程度上这是有道理的,因为我们期望使用reverse_iterator 成员(即base())。
在不知道我有哪种类型的情况下,是否有一种标准方法可以在普通(正向)和包装(反向)迭代器之间进行交换?还是我需要编写一对 SFINAE 函数来适当地返回 std::make_reverse_iterator(it) 和 it.base()?
【问题讨论】:
-
请提供您实际需要这种可能性的代码。
-
您将不得不编写自己的
reverse_iterator函数来交换它。 this 应该对此有所帮助。 -
@r3musn0x - 如果可以的话,我会坚持使用minimal reproducible example。无需使用太多代码来解决问题。总而言之,这是一个回文测试 - 一个传递正向和反向迭代器并使用
std::mismatch()来查看以该点为中心的回文数的函数。我可以对参数进行更多限制,以便前向迭代器必须排在第一位(或最后一位)... -
@Nathan 这就是我愿意听到的。我可能会这样做并写一个自我回答(如果有人创造了更好的技术,他们很清楚可以添加)。
-
@TobySpeight,只是不清楚为什么不能在需要时使用
base()。当您不知道它是否已经反转时,您是否在上下文中使用std::make_reverse_iterator?我真的无法想象这个用例。
标签: c++ iterator reverse-iterator