You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用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;
    }
}

关键细节说明

  1. std::cref的作用:使用std::cref将Person和Account包装为std::reference_wrapper,存入元组时不会拷贝原对象,而是保留引用关系,保证性能和原对象的可访问性。
  2. views::transform嵌套:外层transform遍历每个Person,内层transform将当前Person与他的每个Account绑定为元组。
  3. views::join扁平化:将每个Person对应的元组序列合并成一个连续的视图,实现类似嵌套循环的遍历效果。
  4. 原代码修正:注意原代码中存在笔误iAcount,应改为iAccount,否则会导致编译错误。

内容的提问来源于stack exchange,提问作者awakenx2

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.22 18:15:27