Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to cache a lambda in c++0x?

I'm trying to work with lambda's in C++ after having used them a great deal in C#. I currently have a boost tuple (this is the really simplified version).

typedef shared_ptr<Foo> (*StringFooCreator)(std::string, int, bool)
typedef tuple<StringFooCreator> FooTuple

I then load a function in the global namespace into my FooTuple. Ideally, I would like to replace this with a lambda.

tuplearray[i] = FooTuple([](string bar, int rc, bool eom) -> {return shared_ptr<Foo>(new Foo(bar, rc, eom));});

I can't figure out what the function signature should be for the lambda tuple. Its obviously not a function pointer, but I can't figure out what a lambda's signature should be. The resources for lambda's are all pretty thin right now. I realize C++0x is in flux at the moment, but I was curious about how to get this to work. I also realize there are simpler ways to do this, but I'm just playing around with C++0x. I am using the Intel 11.1 compiler.

like image 458
Steve Avatar asked Dec 24 '09 19:12

Steve


3 Answers

The -> operator sets the return type of the lambda, in the case of no return type it can be omitted. Also, if it can be inferred by the compiler you can omit the return type. Like Terry said, you can't assign a lambda to a function pointer (GCC improperly allows this conversion) but you can use std::function.

This code works on GCC and VC10 (remove tr1/ from the includes for VC):

#include <tr1/tuple>
#include <tr1/functional>
#include <tr1/memory>

using namespace std;
using namespace std::tr1;

class Foo{};
typedef function<shared_ptr<Foo>(string, int, bool)> StringFooCreator;
typedef tuple<StringFooCreator> FooTuple;

int main() {
    FooTuple f(
        [](string bar, int rc, bool eom) {
            return make_shared<Foo>();
        }
    );

    shared_ptr<Foo> pf = get<0>(f)("blah", 3, true);
}
like image 138
joshperry Avatar answered Nov 07 '22 15:11

joshperry


From Visual C++ Blog

I mentioned storing lambdas in tr1::functions. But you shouldn't do that unless it's necessary, as tr1::function has some overhead. If you want to reuse a lambda, or simply want to give it a name, you can use auto.

like image 3
Nikola Smiljanić Avatar answered Nov 07 '22 16:11

Nikola Smiljanić


You should be able to store a lambda in a std::function. In your example, try storing it in a

std::function<std::shared_ptr<Foo>(std::string,int,bool)>

Don't forget about auto (although you won't be able to make an array of auto's, etc).

like image 1
Terry Mahaffey Avatar answered Nov 07 '22 16:11

Terry Mahaffey