0

Can boost::lambda be used recursively?

This doesn't compile:

using namespace boost::lambda;

auto factorial = (_1 == 0) ? 1 : factorial(_1-1);

Is there a suggested workaround?

EDIT: Regarding using C++11 lambdas: The following does not compile on VS2012:

std::function<int(int)> factorial;
factorial = [&factorial](int p)->int { return (p == 0) ? 1 : p*factorial(p-1); };

int main(int argc, char* argv[])
{
    int i = factorial(5);
return 0;
}

ANOTHER EDIT: Strangely, this one works fine:

std::function<int(int)> factorial =
    [&](int p)->int { return (p == 0) ? 1 : p*factorial(p-1); };

int main(int argc, char* argv[])
{
    int i = factorial(5);
return 0;
}
6
  • 1
    If you're using C++11 already, why not use a std::function and a builtin recursive lambda? stackoverflow.com/questions/2067988/… Commented Mar 1, 2013 at 18:47
  • boost::lambda seems to be a bit more stable and flexible then the msvc C++11 lambda implementation... Commented Mar 1, 2013 at 18:53
  • What problems are you experiencing with the VC++ implementation of lambdas? I've used them quite a bit without seeing any issues (well, no issues since SP1 anyway). Commented Mar 1, 2013 at 18:57
  • @RichardJ.RossIII - See the EDIT. Still no go. Commented Mar 1, 2013 at 20:03
  • @DavidH It compiles for me (with clang and a warning, but executes fine) if you put the initializer with the declaration. Commented Mar 1, 2013 at 20:06

2 Answers 2

1

Lambda functions can't directly call themselves because they don't have a name.

The workaround is simple: use a named function.

Sign up to request clarification or add additional context in comments.

1 Comment

Not entirely true - if you were to get the base address of the function pointer of the lambda you could theoretically cast that to the proper type, and then call it to be recursive. Probably not worth the cost, though.
0

The simplest way I've found with regular C++11 lambdas is to declare the variable that will contain the lambda first, then define it and create the lambda. Already being declared allows for the declaration to be used in the definition/lambda itself. Eg:

std::function<int (int)> factorial = nullptr;
factorial = [](int x) -> int {
     if (x <= 1) {
         return 1;
     } else {
         return (x * factorial(x-1));
     }
 };

So far I haven't had any problems with that method, although you do have to know the signature for the declaration and I don't know whether it works with boost::lambda (I would assume so?).

2 Comments

This is not recursive; and if you make it so, it does not compile (on VS2012)
The example is not, I'll fix that. It (or something very similar, I don't have access to a proper compiler atm) most certainly does compile, I use it fairly often.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.