What's the notation for declaring a lambda variable, or function parameter, without the use of auto
or templates? Is there any way to do so? Or does the compiler define a unique class object for each lambda whose name is unknown to the programmer before compile time? If so, why? Can't they just be passed as some sort of function pointer? It would be a major disappointment if that were not possible.
Asked
Active
Viewed 5.7k times
65

R. Martinho Fernandes
- 228,013
- 71
- 433
- 510

slartibartfast
- 4,348
- 5
- 31
- 46
-
"*It would be a major disappointment if that were not possible.*" Why? How could that possibly be useful? – ildjarn Nov 14 '11 at 19:33
-
@ildjarn For runtime lambda! – fstamour Feb 18 '13 at 01:42
2 Answers
61
Lambdas may hold state (like captured references from the surrounding context); if they don't, they can be stored in a function pointer. If they do, they have to be stored as a function object (because there is no where to keep state in a function pointer).
// No state, can be a function pointer:
int (*func_pointer) (int) = [](int a) { return a; };
// One with state:
int b = 3;
std::function<int (int)> func_obj = [&](int a) { return a*b; };

Todd Gardner
- 13,313
- 39
- 51
-
Oh, I get it. So that's why they're of undetermined type, because they could be a function object with a few member variables? – slartibartfast Nov 13 '11 at 04:29
-
I suspect having an indeterminate type is more a C++ standard thing; IIRC, most of the literals in c++ don't actually have a defined "type", rather, they are a literal that can convert to different types (like, a string literal is not a const char *. It can become a const char * or a char *). I suspect this gives implementations some leeway? But certainly one of the benefits of this is it allows a literal to become multiple types. (some of this is on shaky memories of the standard though, so reader bewarned) – Todd Gardner Nov 13 '11 at 04:35
-
2Actually a string literal is a `const char[N]` where N is the number of characters in it plus one. – R. Martinho Fernandes Nov 13 '11 at 16:24
-
The second solution does seem to violate the "without templates" part of the question. That's unavoidable, though: the type of a lambda cannot be named, so you either have to use a _standard_ conversion to another type or use templates. (User-defined, non-template conversions can't name the lambda source type either). So, as it happens the only conversion from lambda types that does not involve templates is to a function pointer. – MSalters Nov 17 '11 at 14:57
26
You can use a polymorphic wrapper for a function object. For example:
#include <functional>
std::function<double (double, double)> f = [](double a, double b) { return a*b };

David Alber
- 17,624
- 6
- 65
- 71