2

I have read the item31 of "Effective Modern C++" and web page of http://en.cppreference.com/w/cpp/language/lambda and wonder if I can define a lambda by its definite type instead of the wrapped type of std::function or keyword of auto and how can I accomplish that.

for instance, for the type int:

auto x_1 = 5; // type deduction
int x_2 = 5;  // defined by definite type
// both x_1, x_2 are int variables of value 5

now, when the problem comes to the lambda:

auto f_1_0 = []()->int{return 5;};
std::function<int(void)> f_1_1 = []()->int{return 5;};
SomeType f_2 = []()->int{return 5;}; // what's the SomeType here?
Liu Weibo
  • 434
  • 5
  • 16
  • 4
    Lambda's have unutterable type names. Their types have to be deduced. – Justin Nov 27 '17 at 23:49
  • 4
    If you want a concrete type name build a functor. Lambdas are meant to be anonymous. – NathanOliver Nov 27 '17 at 23:50
  • 1
    Technically you can, i.e. by re-implementing `std::function`, but as your actual question appears to be whether you can discover the lambda's typename: That you can't do. – Baum mit Augen Nov 27 '17 at 23:50
  • It depends what you want to do with the name of the lambda. If you just want to see what the compiler came up with, you can use `print_T()` where `template print_T() { std::cout << __PRETTY_FUNCTION__ << '\n'; }`. – Henri Menke Nov 28 '17 at 01:52
  • @Henri "__PRETTY_FUNCTION__" is not a standard thing. Gcc, right? (I admire your ability to get this editor to display __PRETTY_FUNCTION___ correctly.) – Jive Dadson Nov 28 '17 at 02:06
  • @JiveDadson `__PRETTY_FUNCTION__` is non-standard, but it's available in GCC and Clang. – Henri Menke Nov 28 '17 at 02:54

3 Answers3

7

Each lambda expression has its own unique type.

Here the expressions f_1 and f2 have different types.

auto f_1 = []()->int {return 5; }; 
auto f_2 = []()->int {return 5; }; 

Assigning f_2 = f_1 is illegal.

The standard says the types are "unnamed." In practice, the compiler probably makes up a new, hiiden typename for each lambda. Visual C++17 gave them the following names.

classmain::<lambda_7e9d7fb093569d78a8c871761cbb39d7>
classmain::<lambda_8f061a3967cd210147d6a4978ab6e125>

Not very useful information.

Jive Dadson
  • 16,680
  • 9
  • 52
  • 65
2

The standard says that the type of the lambda is unnamed so the implementation creates a implementation defined name it uses similar to the other unnamed classes, structs enumc etc.

ISO C++: 5.1.2 Lambda expressions [expr.prim.lambda]

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.

The standard also says that the lambda 'behaves like a function' so you it could be used with the std::function template:

[Note: A closure object behaves like a function object (20.9).—end note]

And if you really want to have names for your can use the old-fashioned functors and do all the work the compiler do for you with the lambdas.

Mihayl
  • 3,821
  • 2
  • 13
  • 32
1

in some cases you can use function pointers (using mvcpp, 0x17):

auto usingAuto = []() {
    cout << "autoMagick" << endl;
};
void(*pureCpp)() = []() {
    cout << "pureCpp" << endl;
};

//pureCpp = usingAuto; //you can even assing function pointers from lambdas
//usingAuto = pureCpp;  //error
pureCpp();
usingAuto();
CptL0g
  • 11
  • 1