Boost logo

Boost :

Subject: Re: [boost] Using C++11 lambdas to replace Phoenix in MPL expressions
From: Michel Morin (mimomorin_at_[hidden])
Date: 2012-03-25 13:36:19


Augustus Saunders wrote:
>>> The approach with boost::optional cannot do this.
>>> In-place factories need a lambda object itself.
>>> So maybe you're not interested in this approach.
>>> (But, please note that we cannot know the type of lambda expression
>>> without actually constructing lambda objects.)
>
> Since lambdas are copy-constructable, I'm unclear
> what problem the boost::optional suggestion was
> trying to solve.

OK, the boost::optional approach is not useless for your problems.
Let's forget about it ;)

For stateless lambdas, use the following:

// Helper metafunctions to determine the function type of C++11 lambdas
template <typename T>
struct function_type;

template <typename Ret, typename Class, typename... Args>
struct function_type<Ret (Class::*)(Args...)>
{
    typedef Ret type(Args...);
};

template <typename Ret, typename Class, typename... Args>
struct function_type<Ret (Class::*)(Args...) const>
{
    typedef Ret type(Args...);
};

template <typename Lambda>
struct lambda_function_type
{
    typedef typename function_type<decltype(&Lambda::operator())>::type type;
};

// Wrapper class of C++11 lambdas
template <typename Lambda>
struct lambda
{
    static typename lambda_function_type<Lambda>::type * f_ptr;

    template <typename... Args>
    auto operator()(Args&&... args) const ->
decltype(f_ptr(static_cast<Args&&>(args)...))
    {
        return f_ptr(static_cast<Args&&>(args)...);
    }
};

template <typename Lambda>
typename lambda_function_type<Lambda>::type * lambda<Lambda>::f_ptr = 0;

template <typename Lambda>
lambda<Lambda> make_lambda(Lambda const& l)
{
    lambda<Lambda>::f_ptr = l;

    return lambda<Lambda>();
}

// Sample code
#include <iostream>

int main (int argc, char* argv[])
{
    auto x = make_lambda([](int x, int y){ return x + y; });

    decltype(x) y; // Default construct y
    std::cout << y(5, 9) << std::endl; // Evaluate stateless lambda

    return 0;
}

Regards,
Michel


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk