C++11 lambda in decltype
Asked Answered
A

3

36

For the following code:

auto F(int count) -> decltype([](int m) { return 0; }) 
{                                                               
    return [](int m) { return 0; };                                  
}

g++ 4.5 gives the errors:

test1.cpp:1:32: error: expected primary-expression before 'int'
test1.cpp:1:32: error: expected ')' before 'int'

What is the problem? What is the correct way to return a lambda from a function?

Attention answered 31/1, 2011 at 0:15 Comment(0)
O
48

You cannot use a lambda expression except by actually creating that object- that makes it impossible to pass to type deduction like decltype.

Ironically, of course, the lambda return rules make it so that you CAN return lambdas from lambdas, as there are some situations in which the return type doesn't have to be specified.

You only have two choices- return a polymorphic container such as std::function, or make F itself an actual lambda.

auto F = [](int count) { return [](int m) { return 0; }; };
Obsequies answered 31/1, 2011 at 0:23 Comment(6)
+1 for clearing up the problem. I checked out the SC22-N-4411 draft and found sort of scary the phrase that says that "each lambda expression has a unique type".Bartko
@6502: Yes, that fact made me realize why my executable size suddenly increased 10% due to stable_sort.Kellsie
It's not scary at all. Inlining makes your program execute faster.Obsequies
Why don't decltype(std::declval<[](){}>()) work? Isn't this what declval is for? To create an instance of a type in unevaluated context? Is there no way to prohibit dumb optimizers to allocate a function pointer on the stack?Hobnailed
Not possible because for one, [](){} is not a type and therefore cannot be passed as a template parameter... but secondly because it simply doesn't actually make any sense.Obsequies
@Hobnailed [](){} isn't a type, so we'd need std::declval<decltype([](){})>, which just leads back to the same problem. It's the chicken and the egg, basically: We can't deduce a lambda's type because it can't be passed to decltype, but we can't turn it into a decltype-friendly value because we'd need its type to do that. It's kinda annoying, really.Ahmednagar
M
13

With C++14, you can now simply omit the return type:

auto F(int count)
{
    return [](int m) { return 0; };
}
Muldoon answered 15/9, 2017 at 20:16 Comment(0)
Z
11

something like this fits your needs?

#include <functional>

std::function<int(int)> F(int count)
{                                                               
    return [](int m) { return 0; };                                  
}
Zoologist answered 31/1, 2011 at 0:25 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.