c++ - Lambda 返回 lambda 错误地推断返回类型?

标签 c++ visual-studio-2012 compiler-construction c++11 lambda

这个问题是我最近的一个问题的延续:
What is this compiler error when using a lambda as a template parameter?

十一月2014 年 1 月 11 日:Microsoft 已回应称,此错误的修复应该出现在 Visual C++ 的下一个主要版本中。


此代码无法使用 VS2012(更新 2)编译:

int main(int argc, char* argv[])
{
    auto f = []()
    {
        int n = 0;
        auto r = [=]{ return n; };
        return r;
    };
    return 0;
}

这是我得到的编译器错误:

1>  main.cpp
1>C:\test\main.cpp(7): error C2440: 'return' : cannot convert from 'main::<lambda_c5d1d707b91a1ddedc06eb080503550c>::()::<lambda_ac357c309731f4971c3269160ed9c24b>' to 'int (__cdecl *)(void)'
1>          No user-defined-conversion operator available that can perform this conversion, or the operator cannot be called

  • C++11规范的代码有问题吗?
  • 根据 VS2012 定义的部分 C++11 支持,代码是否存在问题?
  • 或者这是 VS2012 C++ 编译器错误?

  • 有人可以指出 C++11 规范中讨论 lambda 必须如何隐式转换为函数指针的地方吗?
    • 我记得这只适用于无状态 lambda - 那些带有空捕获子句的 lambda - 内部 lambda r 不是
    • 那么为什么lambda f的推断返回类型会出现为函数指针,即int (__cdecl *)(void)

最佳答案

尽管 GCC 4.7.2 编译了这段代码,但它的格式不正确。初始化 f 的 lambda 表达式对于推导返回类型来说太复杂了。事实上,5.1.2/4 说

If a lambda-expression does not include a trailing-return-type, it is as if the trailing-return-type denotes the following type:

— if the compound-statement is of the form

   { attribute-specifier-seq[opt] return expression ; }

the type of the returned expression after lvalue-to-rvalue conversion (4.1), array-to-pointer conversion (4.2), and function-to-pointer conversion (4.3);

— otherwise, void.

因此,在此示例中,返回类型为 void 但 lambda 返回的是其他内容。代码不应编译。

我同意 Visual Studio 给出的信息具有误导性。

更新:关于这个问题

So would it be correct to say "In C++11, you cannot define a lambda that returns a stateful lambda"?

没有。根据下面的 C++11 引用,lambda 返回的类型是 void,除非 lambda 的主体仅包含一行带有 return expression;。因此,如果您设法在返回表达式中创建有状态的 lambda,那么这很好。例如,下面的代码可以在 GCC 4.7.2、Clang 3.2 和 Intel 编译器 13.1.0 中编译:(由于上述错误,它无法在 VS2012 中编译。)

#include <iostream>

int main() {
  int n = 5;
  auto f = [=] {
      return [=]{ return n; }; // creates a stateful lambda and returns it in a single line
  };
  std::cout << f()() << std::endl;
  return 0;
}

关于c++ - Lambda 返回 lambda 错误地推断返回类型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16726014/

相关文章:

c# - 类库错误不包含适合入口点的静态方法 'Main'

java - 在asm java编译器中创建一个数组

java - 将Java编译成PHP?

assembly - x86 的交叉编译 arm 程序集

c++ - 新创建的暂停进程的 EIP 仅在 Windows XP 上失败 - kernel32.dll 镜像下的 EIP?

c# - 我可以更改 RDLC 中的 PDF 分辨率吗

c++ - Visual Studio 2012 中的智能指针错误

c++ - 如何自定义我的按钮?

c++ - 我应该怎么做而不是函数模板的部分特化?

c++ - 简单的 MPI_Scatter 尝试