C++lambda函数访问写入冲突

C++ lambda function access write violation

本文关键字:冲突 访问 函数 C++lambda      更新时间:2023-10-16

我正在学习如何将C++lambda函数与<functional>function类一起使用。我正在努力解决这个代码高尔夫作为练习(挑战是咖喱晚餐(

我有这个功能:

// This creates a function that runs y a number of 
// times equal to x's return value.
function<void()> Curry(function<int()> x, function<void()> y)
{
    return [&]() {
        for (int i = 0; i < x(); i++)
        {
            y();
        }
    };
}

为了测试这一点,我的main((中有以下代码:

auto x = [](){ return 8; };
auto y = [](){ cout << "test "; };
auto g = Curry(x, y);

这会将Access violation reading location 0xCCCCCCCC.抛出Functional.h

然而,当我将lambda函数从Curry((中复制粘贴到我的main中时,如下所示:

auto x = [](){ return 8; };
auto y = [](){ cout << "test "; };
auto g = [&]() {
    for (int i = 0; i < x(); i++)
    {
        y();
    }
};

我使代码按预期运行。为什么会发生这种情况?

您遇到了一些问题。

此处:

  return [&]() {

您通过引用捕获。您捕获的任何变量的生存期都必须超过您自己的生存期。这意味着运行lambda在您捕获的变量&使用寿命结束。当您返回这个lambda并捕获本地状态时,这似乎很可能发生。(注意,我说的是变量——由于标准中的一个怪癖,[&]捕获的是变量,而不是变量引用的数据,所以即使用[&]捕获&函数参数也是不安全的。这可能会在标准的未来版本中发生变化……在lambda实现中,这组特定的规则允许进行巧妙的优化(将[&] lambdas减少为具有1个指针值的state(!((,但它也引入了C++中唯一一种对引用变量有效引用的情况…(

将其更改为

  return [=]() {

以及价值捕获。

甚至:

  return [x,y]() {

明确列出您的捕获。

当使用不超过当前作用域的lambda时,我使用[&]。否则,我会通过价值明确地捕捉我将要使用的东西,因为在这种情况下,生命周期很重要。

下一篇:

    for (int i = 0; i < x(); i++)

您为每个循环迭代运行一次x。看起来很傻!

相反:

    auto max = x();
    for (auto i = max; i > 0; --i)

它运行max次,如果x的返回值被更改为unsigned int或其他什么,它就会工作。

或者:

    int max = x();
    for (int i = 0; i < max; ++i)

两者都运行x一次并且如果x返回-1则表现更好。

或者,您可以使用模糊运算符-->:

    int count = x();
    while( count --> 0 )

如果您想使代码不可读。;(