如何用std::ranges::view替代嵌套循环并访问多层上下文
用std::ranges::view替换嵌套循环并保留Person与Account引用
要实现需求,我们可以通过std::views::transform将每个Person转换为其自身与对应Account的元组序列,再用std::views::join将所有序列扁平化为一个视图。核心是用std::cref保留对象引用,避免不必要的拷贝。
完整实现代码
#include <string> #include <vector> #include <iostream> #include <ranges> #include <tuple> #include <functional> // 用于std::cref struct Account { int money; }; struct Person { std::string name; std::vector<Account> accounts; }; int main() { // 构造测试数据 std::vector<Person> persons = { {"Alice", {{100}, {200}}}, {"Bob", {{300}}} }; // 生成包含Person和Account引用的元组视图 auto person_account_view = persons | std::views::transform([](const Person& p) { // 对当前Person的每个Account,生成(p, Account)的元组 return p.accounts | std::views::transform([&p](const Account& a) { return std::make_tuple(std::cref(p), std::cref(a)); }); }) | std::views::join; // 扁平所有元组序列 // 遍历视图 for(const auto& pair : person_account_view) { const auto& person = std::get<0>(pair); const auto& account = std::get<1>(pair); std::cout << person.name << ": " << account.money << std::endl; } }
关键细节说明
std::cref的作用:使用std::cref将Person和Account包装为std::reference_wrapper,存入元组时不会拷贝原对象,而是保留引用关系,保证性能和原对象的可访问性。views::transform嵌套:外层transform遍历每个Person,内层transform将当前Person与他的每个Account绑定为元组。views::join扁平化:将每个Person对应的元组序列合并成一个连续的视图,实现类似嵌套循环的遍历效果。- 原代码修正:注意原代码中存在笔误
iAcount,应改为iAccount,否则会导致编译错误。
内容的提问来源于stack exchange,提问作者awakenx2
相关产品推荐
相关产品推荐

