[英]C++ lambda function access write violation
我正在学习如何使用C ++ lambda函数和<functional>
的function
类。 我正在尝试解决这个Code Golf作为练习(挑战是咖喱晚餐)
我有这个功能:
// 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个指针值的状态(!)),但它也引入了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 )
如果你想让你的代码不可读。 ;)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.