std::invoke调用lambda返回值无法绑定非const左值引用报错
错误原因
未显式指定返回类型的lambda,在自动推导返回值类型时会执行**类型退化(decay)**规则:推导过程会移除表达式的引用、顶层const/volatile限定符,数组、函数类型会退化为对应指针类型。
这段代码里lambda的两个return分支实际返回的都是foo&类型:
foos.emplace_back()本身返回vector新插入元素的左值引用foos[new_index]本身返回vector下标对应位置元素的左值引用
但自动推导返回类型时,返回值的引用层被直接剥离,lambda最终返回的是foo类型的右值(临时拷贝对象)。此时用非const左值引用foo& new_foo绑定右值,就会触发编译报错。std::invoke只是原样透传lambda的返回值,本身不是错误来源。
修复方案
显式为lambda指定返回类型为foo&,强制编译器按左值引用返回,跳过自动推导的类型退化逻辑即可。
修复后的可运行代码如下:
#include <iostream> #include <cstdlib> #include <functional> #include <vector> struct foo { int a; }; int main() { std::vector<foo> foos = {foo{22}}; std::size_t new_index = -1; bool append = (rand() & 1) == 1; foo& new_foo = std::invoke([&foos,&new_index,append]() -> foo& { if(append) { new_index = foos.size(); return foos.emplace_back(); }else { new_index = 0; return foos[new_index]; } }); // 可正常修改引用指向的对象 new_foo.a = 100; return new_foo.a; }
原问题复现代码缺少
<vector>头文件,修复版本已补充,避免触发其他编译错误。
内容的提问来源于stack exchange,提问作者user3001150
相关产品推荐
相关产品推荐

