我在从 lambda 返回引用时遇到一些麻烦。 此代码有效:
std::function<int*(int*)> funct;
funct = [](int *i){
++*i;
return i;
};
int j = 0;
std::cout << *funct(&j) << j;
输出:1 1
但不是这个:
std::function<int&(int&)> funct;
funct = [](int &i){
++i;
return i;
};
int j = 0;
std::cout << funct(j) << j;
构建错误:
C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\include ype_traits:1441: 错误: C2440: 'return': 无法从 'int' 转换为 'int &'
为什么会出现这种情况?
lambda 推导返回类型,就像使用
auto
指定的那样。 auto ret = i;
会将 ret
推断为 int
。
一种解决方案是显式声明 lambda 的返回类型:
funct = [](int &i) -> int& {
++i;
return i;
};
正如评论中提到的另一种方式是
funct = [](int &i) -> decltype(auto) {
++i;
return i;
};
本质上告诉编译器不要进行任何推导,而只使用该类型,就像在返回表达式上使用了
decltype
一样。
如果您对确切的规则感到好奇,请查看文档,其中还有关于
auto
的部分和一些关于 decltype(auto)
的内容。