0

C++20 引入了views::elements,views::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});
4

2 回答 2

2

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

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

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));
于 2021-01-27T04:04:53.520 回答
2

可以通过调用.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});
于 2021-01-27T04:35:38.583 回答