gpt4 book ai didi

c++ - 在 C++11 中,什么时候应该按值捕获 lambda 表达式的绑定(bind)变量?

转载 作者:可可西里 更新时间:2023-11-01 17:04:22 30 4
gpt4 key购买 nike

我有一个Visual Studio 2010 C++程序,主要功能是:

vector<double> v(10);

double start = 0.0; double increment = 10.0;
auto f = [&start, increment]() { return start += increment; };
generate(v.begin(), v.end(), f);
for(auto it = v.cbegin(); it != v.cend(); ++it) { cout << *it << ", "; }

cout << endl << "Changing vars to try again..." << endl;
start = 15; increment = -1.5;
generate(v.begin(), v.end(), f);
for(auto it = v.cbegin(); it != v.cend(); ++it) { cout << *it << ", "; }
return 0;

当我在 MS Visual Studio 中编译它时,第一个生成符合我的预期,结果是“10, 20, ... 100,”。第二个没有; lambda“看到”start 的变化,但没有看到 increment 的变化,所以我得到“25, 35, ... 115,”。

MSDN explains那个

The Visual C++ compiler binds a lambda expression to its captured variables when the expression is declared instead of when the expression is called. ... [T]he reassignment of [a variable captured by value] later in the program does not affect the result of the expression.

所以我的问题是:这是符合标准的 C++11 行为,还是 Microsoft 自己的古怪实现?奖励:如果它标准行为,为什么标准是这样写的?它与强制函数式编程的引用透明性有关吗?

最佳答案

使用 lambda 表达式,绑定(bind)变量在声明时被捕获。

这个例子会很清楚: https://ideone.com/Ly38P

 std::function<int()> dowork()
{
int answer = 42;
auto lambda = [answer] () { return answer; };

// can do what we want
answer = 666;
return lambda;
}

int main()
{
auto ll = dowork();
return ll(); // 42
}

很明显,捕获必须发生在调用之前,因为被捕获的变量在以后甚至不再存在(不在作用域内,也不在生命周期内)。 p>

关于c++ - 在 C++11 中,什么时候应该按值捕获 lambda 表达式的绑定(bind)变量?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7881149/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com