加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c – 奇怪的未定义的行为与棘手的lambda表达式

发布时间:2020-12-16 03:33:44 所属栏目:百科 来源:网络整理
导读:我一直在努力反对那个正在危及我的一个项目的lambda表达式的问题.我找到了一个解决方案,但是我想要明确地了解它是如何和为什么它的工作,如果它是可靠的. #include iostream#include functional#include unordered_maptypedef std::functionconst int(const i
我一直在努力反对那个正在危及我的一个项目的lambda表达式的问题.我找到了一个解决方案,但是我想要明确地了解它是如何和为什么它的工作,如果它是可靠的.
#include <iostream>
#include <functional>
#include <unordered_map>

typedef std::function<const int&(const int&)> Callback;

int f(int i,Callback callback) {
    if (i <= 2) return 1;
    return callback(i-1) + callback(i-2);
}

int main(void) {

    std::unordered_map<int,int> values;

    Callback callback = [&](const int& i) {
        if (values.find(i) == values.end()) {
            int v = f(i,callback);
            values.emplace(i,v);
        }
        return values.at(i);
    };

    std::cout << f(20,callback) << std::endl;

    return 0;

}

我知道这是计算第20个斐波纳契数字的疯狂方法,但它是我能够阐述的最紧凑的SSCCE.

如果我用g -O0编译上面的代码,我执行程序,我得到6765,这实际上是第20个斐波那契数.如果我用-O1,-O2或-O3编译,我得到262144,这是垃圾.

如果我使用Valgrind配置程序(用-O0 -g编译),我得到条件跳转或移动取决于行std :: cout上的未初始化值(<<< f(20,回调)<<的std :: ENDL;但堆栈跟踪没有说什么有用. 我不知道为什么我这样做最终:

Callback callback = [&](const int& i) -> const int& {

通过这个小小的修改,一切都可以按预期的方式进行任何优化级别的编译,而Valgrind报告没有问题.

你能帮我了解发生了什么吗?

解决方法

没有 – > const int& lambda的返回类型是int.由于Callback的返回类型是const int& amp; amp; amp; amp; amp; amp; amp; amp; amp; amp; amp; amp; amp; amp; amp;未定义的行为.

对于这个简单的例子,容易的修复是根本不使用引用(Example at Coliru),但是我假设你的真正的代码是处理比int更重的对象.不幸的是,当您分配一个返回非引用的函数返回类型为引用的std ::函数时,std ::函数未指定为警告.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读