Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the type of lambda when deduced with "auto" in C++11?

People also ask

What is lambda expression in C++11?

In C++11 and later, a lambda expression—often called a lambda—is a convenient way of defining an anonymous function object (a closure) right at the location where it's invoked or passed as an argument to a function.

What is auto lambda expression?

Immediately invoked lambda expression is a lambda expression which is immediately invoked as soon as it is defined. For example, #include<iostream> using namespace std; int main(){ int num1 = 1; int num2 = 2; // invoked as soon as it is defined auto sum = [] (int a, int b) { return a + b; } (num1, num2);

How many types of lambda are there?

1) Argument-list: It can be empty or non-empty as well. 2) Arrow-token: It is used to link arguments-list and body of expression. 3) Body: It contains expressions and statements for lambda expression.

What is the data type of a lambda expression C++?

Lambda expressions in C++14 are functions that can be treated as any other object, such as a class or struct. They can utilize variables defined in the same scope, 'capturing' them implicitly or explicitly by value or reference. A lambda object (also known as 'closure object') can be called like a normal function.


The type of a lambda expression is unspecified.

But they are generally mere syntactic sugar for functors. A lambda is translated directly into a functor. Anything inside the [] are turned into constructor parameters and members of the functor object, and the parameters inside () are turned into parameters for the functor's operator().

A lambda which captures no variables (nothing inside the []'s) can be converted into a function pointer (MSVC2010 doesn't support this, if that's your compiler, but this conversion is part of the standard).

But the actual type of the lambda isn't a function pointer. It's some unspecified functor type.


It is a unique unnamed structure that overloads the function call operator. Every instance of a lambda introduces a new type.

In the special case of a non-capturing lambda, the structure in addition has an implicit conversion to a function pointer.


[C++11: 5.1.2/3]: The type of the lambda-expression (which is also the type of the closure object) is a unique, unnamed non-union class type — called the closure type — whose properties are described below. This class type is not an aggregate (8.5.1). The closure type is declared in the smallest block scope, class scope, or namespace scope that contains the corresponding lambda-expression. [..]

The clause goes on to list varying properties of this type. Here are some highlights:

[C++11: 5.1.2/5]: The closure type for a lambda-expression has a public inline function call operator (13.5.4) whose parameters and return type are described by the lambda-expression’s parameter-declaration-clause and trailing-return-type respectively. [..]

[C++11: 5.1.2/6]: The closure type for a lambda-expression with no lambda-capture has a public non-virtual non-explicit const conversion function to pointer to function having the same parameter and return types as the closure type’s function call operator. The value returned by this conversion function shall be the address of a function that, when invoked, has the same effect as invoking the closure type’s function call operator.

The consequence of this final passage is that, if you used a conversion, you would be able to assign LAMBDA to pFptr.


#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;
}

The function types are indeed same, but the lambda introduces new type (like a functor).


It should also note that lambda is convertible to function pointer. However typeid<> returns a non-trvial object which should differ from lambda to generic function pointer. So the test for typeid<> is not a valid assumption. In general C++11 do not want us to worry about type specification, all that matter if a given type is convertible to a target type.