有没有可能使用转换后的迭代器获取原始值的方法?

问题描述

C++20 引入了 views::elementsviews::keysviews::values 来轻松处理一系列类似元组的值:

std::vector v{std::tuple{'A',1},{'B',2},{'C',3}};
auto it = std::ranges::find(v | std::views::elements<0>,'B');
assert(*it == 'B');

应用适配器后,v | std::views::elements<0>成为每个元组第一个元素的范围,因此ranges::find的返回类型是该转换范围的迭代器类型。

但是有没有可能将 it 转换回原始迭代器类型以获取原始元组?

assert(*magic_revert(it) == std::tuple{'B',2});

解决方法

没有真正的方法可以从 it 获得原始元组,因为 it 指向从原始元组范围构造的 view

不过你可以很容易地解决这个问题:

auto elems = v | std::views::elements<0>;  // name the view

auto it = std::ranges::find(elems,'B');   // find it

// use the distance of it from the beginning of elems,to get an iterator into v
auto orig_it = std::next(std::begin(v),std::distance(std::begin(elems),it));
,

可以通过调用 .base() 来获取底层范围的迭代器。

assert(*it.base() == std::tuple{'B',2});

但使用带有 std::ranges::find 的投影可能更惯用。

std::vector v{std::tuple{'A',1},{'B',2},{'C',3}};
auto it = std::ranges::find(v,'B',[](auto& e) { return std::get<0>(e); });
assert(*it == std::tuple{'B',2});

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...