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;
}
David H
  • 1,461
  • 2
  • 17
  • 37
  • 1
    If you're using C++11 already, why not use a `std::function` and a builtin recursive lambda? http://stackoverflow.com/questions/2067988/recursive-lambda-functions-in-c0x – Richard J. Ross III Mar 01 '13 at 18:47
  • boost::lambda seems to be a bit more stable and flexible then the msvc C++11 lambda implementation... – David H Mar 01 '13 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). – Ferruccio Mar 01 '13 at 18:57
  • @RichardJ.RossIII - See the EDIT. Still no go. – David H Mar 01 '13 at 20:03
  • @DavidH It compiles for me (with clang and a warning, but executes fine) if you put the initializer with the declaration. – Richard J. Ross III Mar 01 '13 at 20:06
  • Once again I am a helpless victim of Microsoft. Maybe it will work in VS2047. – David H Mar 01 '13 at 20:24

2 Answers2

1

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

The workaround is simple: use a named function.

Ferruccio
  • 98,941
  • 38
  • 226
  • 299
  • 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. – Richard J. Ross III Mar 01 '13 at 18:52
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?).

ssube
  • 47,010
  • 7
  • 103
  • 140
  • This is not recursive; and if you make it so, it does not compile (on VS2012) – David H Mar 01 '13 at 19:56
  • 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. – ssube Mar 01 '13 at 22:09