C++ 11 lambda返回引用

NiH*_*HoT 4 c++ lambda c++11

从lambda返回引用我有些麻烦.此代码有效:

std::function<int*(int*)> funct;

funct = [](int *i){
    ++*i;
    return i;
};

int j = 0;
LOG<<*funct(&j)<<j;
Run Code Online (Sandbox Code Playgroud)

输出:1 1

但不是这个:

std::function<int&(int&)> funct;

funct = [](int &i){
    ++i;
    return i;
};

int j = 0;
LOG<<funct(j)<<j;
Run Code Online (Sandbox Code Playgroud)

构建错误:C:\ Program Files(x86)\ Microsoft Visual Studio 14.0\VC\include\type_traits:1441:错误:C2440:'return':无法从'int'转换为'int&'

知道为什么吗?对我来说,这是一回事.

nwp*_*nwp 20

lambda推导出返回类型,如同指定一样auto.auto ret = i;会推断ret成为一个int.

一种解决方案是显式声明lambda的返回类型:

funct = [](int &i) -> int& {
    ++i;
    return i;
};
Run Code Online (Sandbox Code Playgroud)

正如评论中提到的另一种方式

funct = [](int &i) -> decltype(auto) {
    ++i;
    return i;
};
Run Code Online (Sandbox Code Playgroud)

这实际上告诉编译器不要进行任何推断,只是使用类型,就像decltype在返回表达式上使用一样.

如果您对确切的规则感到好奇,请查看文档,其中还有一个部分auto和一点decltype(auto).

  • 或者使用 `decltype(auto)` 作为返回类型!这与“auto”的用法形成对比。也就是说,“decltype(auto) ret = i;”使“ret”成为“i”的引用。 (2认同)
  • 人们说 C++ 的语法晦涩、复杂。他们知道什么:-) (2认同)