在C++ 11中用"auto"推导出lambda的类型是什么?

iam*_*ind 129 c++ lambda typeof auto c++11

我有一种感觉,lambda的类型是一个函数指针.当我进行以下测试时,我发现它是错误的(演示).

#define LAMBDA [] (int i) -> long { return 0; }
int main ()
{
  long (*pFptr)(int) = LAMBDA;  // ok
  auto pAuto = LAMBDA;  // ok
  assert(typeid(pFptr) == typeid(pAuto));  // assertion fails !
}
Run Code Online (Sandbox Code Playgroud)

上面的代码是否缺少任何一点?如果不是那么,typeofauto关键字推导出的lambda表达式是什么?

jal*_*alf 130

lambda表达式的类型未指定.

但它们通常仅仅是仿函数的语法糖.lambda直接转换为仿函数.里面的任何东西[]都变成了构造函数参数和仿函数对象的成员,里面的参数()变成了仿函数的参数operator().

一个没有变量的lambda(在[]s 里面没有任何东西)可以转换成一个函数指针(MSVC2010不支持这个,如果那是你的编译器,但这个转换是标准的一部分).

但是lambda的实际类型不是函数指针.这是一些未指定的仿函数类型.

  • +1为"仅仅是仿函数的语法糖".记住这一点可以避免很多潜在的混乱. (14认同)
  • 函子是任何带有 `operator()` 的东西,基本上是 /sf/ask/24986531/ (5认同)

ava*_*kar 101

它是一个唯一的未命名结构,它使函数调用运算符重载.lambda的每个实例都引入了一种新类型.

在非捕获lambda的特殊情况下,该结构还具有对函数指针的隐式转换.

  • 立新世纪?这是其他人所说的独特性吗?;) (5认同)
  • 对于unicity部分+1,一开始就非常令人惊讶,值得关注. (4认同)
  • 很好的答案。比我的准确多了。+1 :) (3认同)
  • @Ben,它是未命名的,就C++语言而言,没有"编译器决定的名称"这样的东西.`type_info :: name()`的结果是实现定义的,因此它可以返回任何内容.实际上,编译器会为链接器命名类型. (3认同)
  • 最近,当被问到这个问题时,我通常会说 lambda 的类型_has_有一个名称,编译器知道它,但它是不可言传的。 (2认同)

Lig*_*ica 24

[C++11: 5.1.2/3]: 的类型的λ-表达(这也是封闭的对象的类型)是一个独特的,无名不愈合类类型 -称为闭合类型 -其特性如下所述.此类类型不是聚合(8.5.1).闭包类型在包含相应lambda表达式的最小块作用域,类作用域或命名空间作用域中声明.[..]

该子句继续列出此类型的不同属性.以下是一些亮点:

[C++11: 5.1.2/5]:lambda表达式的闭包类型有一个公共inline函数调用操作符(13.5.4),其参数和返回类型分别由lambda-expressionparameter-declaration-clausetrailing-return-type描述.[..]

[C++11: 5.1.2/6]:没有lambda-capturelambda表达式的闭包类型有一个公共的非虚拟非显式const转换函数,用于指向具有与闭包类型的函数调用操作符相同的参数和返回类型的函数.此转换函数返回的值应为函数的地址,该函数在调用时与调用闭包类型的函数调用运算符具有相同的效果.

最后一段话的结果是,如果您使用转换,您将可以分配LAMBDApFptr.


BЈо*_*вић 6

#include <iostream>
#include <typeinfo>

#define LAMBDA [] (int i)->long { return 0l; }
int main ()
{
  long (*pFptr)(int) = LAMBDA;  // ok
  auto pAuto = LAMBDA;  // ok

  std::cout<<typeid( *pAuto ).name() << std::endl;
  std::cout<<typeid( *pFptr ).name() << std::endl;

  std::cout<<typeid( pAuto ).name() << std::endl;
  std::cout<<typeid( pFptr ).name() << std::endl;
}
Run Code Online (Sandbox Code Playgroud)

函数类型确实相同,但 lambda 引入了新类型(如函子)。