You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

C++ Ranges:如何在视图中修改参数?

C++ Ranges:如何在视图中修改参数?

看起来你是想让C++ Ranges的transform视图里的转换逻辑,能响应外部参数的动态变化对吧?从你给出的代码片段来看,当前实现的问题在于lambda值捕获了参数b,后续修改外部的bTemp根本不会影响lambda里的逻辑——因为捕获的是当时的副本,和原变量没关系了。我来帮你调整代码解决这个问题。

首先先把你没写完的代码补全并修改,核心思路是让lambda捕获外部参数的引用,而不是值:

#include <iostream>
#include <vector>
#include <ranges>
#include <algorithm>
#include <numeric>
#include <functional>

namespace{
// 把参数改成非const引用,让lambda能关联到原变量
auto doSomething(bool& b) {
    // 捕获b的引用,这样每次执行lambda都会读取当前的b值
    return [&b](int i){ 
        std::cout << i << ": " << std::boolalpha << b << "   "; 
        return i + 10; 
    };
}
}

int main() {
    std::vector<int> myVector(10);
    std::iota(myVector.begin(), myVector.end(), -3);

    bool bTemp = true;
    // 获取绑定了bTemp引用的转换函数
    auto transformFunc = doSomething(bTemp);
    // 创建惰性求值的transform视图
    auto transformedView = myVector | std::views::transform(transformFunc);

    std::cout << "第一次遍历(bTemp=true):\n";
    for (int val : transformedView) {
        std::cout << val << " ";
    }
    std::cout << "\n";

    // 修改外部参数
    bTemp = false;

    std::cout << "第二次遍历(bTemp=false):\n";
    for (int val : transformedView) {
        std::cout << val << " ";
    }
    std::cout << "\n";
}

关键说明

  1. 引用捕获的作用:把doSomething的参数从const bool b改成bool& b,同时lambda捕获&b,这样lambda每次执行时,都会读取外部变量bTemp的当前值,而不是一开始的副本。
  2. 惰性求值的特性:Ranges视图是惰性的,只有当你遍历视图时,lambda才会真正执行,所以两次遍历会看到不同的b值输出,完美响应参数变化。

如果担心直接捕获引用可能带来的悬垂引用风险(比如lambda的生命周期超过了原变量),可以用std::reference_wrapper包装,写法更安全明确:

auto doSomething(bool& b) {
    // 用std::ref捕获引用包装器,本质还是关联原变量
    return [b_ref = std::ref(b)](int i){
        std::cout << i << ": " << std::boolalpha << b_ref.get() << "   ";
        return i + 10;
    };
}

备注:内容来源于stack exchange,提问作者RocketSearcher

火山引擎 最新活动