joey
joey

Reputation: 21

C++ lambda function without C++0x?

I have a C++11 lambda function and it needs to be realised without C++0x. I tried it with boost.lambda without success so far.

The lambda function captures 4 variables and takes 2 as parameters. In the body of the lambda function are several if/else, cases and around 100 lines of code.

Hope I wrote all information you need.

€: I got it running,thanks. A little follow up question:

My first try was like this:

    Lambda Obj( C, D);
    command ( Obj.operator()(typeA A, typeB B));

Thanks

Upvotes: 1

Views: 341

Answers (3)

Piotr Skotnicki
Piotr Skotnicki

Reputation: 48487

Live demo link:

#include <iostream>
#include <functional>

template <typename Arg1, typename Arg2, typename Cap1, typename Cap2>
struct my_lambda : std::binary_function<Arg1, Arg2, void>
{
    my_lambda(const Cap1& c1, const Cap2& c2) : cap1(c1), cap2(c2) {}

    void operator()(const Arg1& arg1, const Arg2& arg2) const
    {
        // lambda body
        std::cout << (cap1 + cap2 + arg1 + arg2) << std::endl;
    }

    mutable Cap1 cap1;
    mutable Cap2 cap2;
};

template <typename Arg1, typename Arg2, typename Cap1, typename Cap2>
my_lambda<Arg1, Arg2, Cap1, Cap2> lambda(const Cap1& c1, const Cap2& c2)
{
    return my_lambda<Arg1, Arg2, Cap1, Cap2>(c1, c2);
}

int main()
{
    int i = 1, j = 2;
    lambda<int, int>(i, j)(3, 4);

    // same as:
    // [i, j] (int a, int b)
    // {
    //     std::cout << (i + j + a + b) << std::endl;
    // } (3, 4);
}

Upvotes: 0

dalle
dalle

Reputation: 18517

If you're stuck with C++03/C++98 you're better off with creating a functor instead of trying to make Boost.Lambda work with your 100 lines of code. A C++11 lambda is mostly syntactic sugar for creating a functor anyway.

You can easily translate the following lambda:

const auto lambda = [c1, c2, c3, c4](A1 a1, A2 a2) -> RetVal { /*somecode*/ };

Into the following functor:

namespace
{
  struct Functor
  {
    Cap1 c1; Cap2 c2; Cap3 c3; Cap4 c4;

    Functor(Cap1 c1, Cap2 c2, Cap3 c3, Cap4 c4)
    : c1(c1), c2(c2), c3(c3), c4(c4) {}

    RetVal operator()(A1 a1, A2 a2) const
    {
      /*somecode*/
    }
  };
}

Upvotes: 3

This is not what Boost.Lambda is designed for. Your best bet is to turn this into a normal function object.

Simply transform this:

[a, &b, c, &d](args) -> ReturnValue { body; }

Into this:

class Lambda
{
  Type_of_a a;
  Type_of_b &b;
  Type_of_c c;
  Type_of_d &d;

public:
  Lambda(Type_of_a a, Type_of_b &b, Type_of_c c, Type_of_d &d) : a(a), b(b), c(c), d(d) {}

  ReturnValue operator() (args) const
  { body; }
};

And create an instance of the Lambda class where you create the original lambda expression.

You can put the definition of Lambda in an unnamed namespace, to simulate the lambda's unnamed type also.

Upvotes: 6

Related Questions