tags:

views:

537

answers:

2

I've been reading a bit about lambda expressions on the internet recently and it seems to me that C++0x's lambda expressions will not have a single type (or types) that will bind exclusively to lambda expressions -- in other words, lambda expressions will only match template arguments or auto arguments/variables. What happens, as described here, is that

Compilers that support lambdas will create a unique anonymous functor type for each lambda expression

My question is, is that a bad thing? Wouldn't it make sense to have some keyword that matches only to lambda expressions, e.g. lambda, which would work as follows

void f(std::function<int(int)> func)
{
     func(2);
}

template<typename T>
void g(T func)
{
     func(2);
}

void h(lambda func)
{
     func(2);
}

int main()
{
    int fpointer(int);
    struct { int operator()(int var) { return var; } } functor;

    f(fpointer); //ok (actually a linker error, but for the sake of example)
    f(functor); //ok
    f([](int var) { return var; }); //ok

    g(fpointer); //ok
    g(functor); //ok
    g([](int var) { return var; }); //ok

    h(fpointer); //error -- function pointer isn't a lambda expr
    h(functor); //error -- functor isn't a lambda expr
    h([](int var) { return var; }); //ok

    return 0;
}

To be honest, I actually can't see the usefulness of this (especially given that auto accepts lambda expressions, so one could then assign a lambda to a variable), but it still doesn't sit right with me that lambda expressions are anonymous types and cannot be bound specifically to just one particular type (to the exclusion of all others).

In essence, my question is, is it fine that lambda expressions are anonymous (both in terms of utility -- does the lack of a lambda type devoid us of some functionality -- and philosophically -- does it really make sense that lambda expressions always have the 'type' auto)?

+6  A: 

Lambdas are independent types. The code

void h(lambda func)
{
     func(2);
}

doesn't make any sense because lambdas don't have runtime polymorphism. Recall that a lambda is the equivalent of

struct unique_name
{
    return_type operator()(Arg1 a1, Arg2 a2, ... , Argn an)
    {
        code_inside_lambda;
    }
}

Which is itself a unique type. The code above would be the same as saying

void h(class C)
{
     C(2);
}

Which also makes no sense even if we assure that C has operator(). You need a template:

template<typename T>
void g(T func)
{
     func(2);
}

int main()
{
    g([](int x){return x + 2;});
}
rlbond
You make a good point about the idea of having `void h(class C)`, however I *can* do `void h(functor_name C)` which will only match parameters of that particular functor type. I can't do the same with a lambda expression.
GRB
If you need to refer to a particular lambda by name, you should instead define it the old way using a `struct`. A lambda expression is, by definition, anonymous.
rlbond
That's a good point, if you need to specialize to lambda expressions (even though it'd provide no functionality) you're probably using them incorrectly anyway (and would be going against the theory of lambda epxressions). Plus, as I mentioned and as everyone else has mentioned, there would just probably be no utility to it (though litb's right that someone will add a nonstandard compiler extension for it anyway). I've accepted this answer
GRB
+3  A: 

I see no reason to differentiate function types based on whether the function has a name or not. Lambda functions are just a shorthand, allowing you to define a convenience function easily. Name or no name, the behaviour of the function when called is the same.

Think of it this way. An early version of your software has a predicate defined as an anonymous function. Over time, requirements get more complex, and your predicate gets more complex too - and maybe you need to call it from more than one place. The sensible thing to do is to refactor so that you have a named function.

There's no reason why the called function (the one that calls the predicate) should care about that. Simple or complex, named or anonymous - it's still just a predicate function.

One minor issue is that of closures - I haven't checked, but with a bit of luck, C++ will get nested named functions with closures as well as lambdas.

Steve314