gpt4 book ai didi

C++ lambda 函数访问写冲突

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:15:05 26 4
gpt4 key购买 nike

我正在学习如何将 C++ lambda 函数与 <functional> 一起使用的 function类(class)。我正在尝试解决这个 Code Golf作为练习(挑战是晚餐吃 curry )

我有这个功能:

// 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 中。

然而,当我像这样从 Curry() 内部复制粘贴 lambda 函数到我的 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 个指针值的状态(!)),但它也引入了 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 )

如果你想让你的代码不可读。 ;)

关于C++ lambda 函数访问写冲突,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23395417/

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