Monday, July 12, 2010

Nested Functions in C++

Although c++ does not natively support nested functions, you can do a trick to support them using structs/classes.

In my other blog post I talked about how lambdas can be used as nested functions, and I also showed a way to do recursion with lambdas. If you have access to c++0x, then the nicer way to do nested functions is using lambdas, but if you don't, then you can use the nested-class trick.

Although it may sound odd, you can declare a struct/class in a function. And then this struct/class can have a static method which you can call.

Here's one version of it:

int main() {
struct factClass {
static int factorial(int x) {
return (x <= 1) ? 1 : x * factorial(x-1);
}
};

cout << factClass::factorial(5) << endl; // Prints '120'
return 0;
}


Okay real quickly I want to point out that in c++, structs and classes are the same thing; the only difference is the default access between structs and classes.

With struct all the method/variables are 'public' by default, and with classes they're 'private' by default.
You can change the behavior by specifying "public:" or "protected:" or "private:" keywords for both structs and classes.
When I first started with c++ I didn't know this, so that's why I'm mentioning it :D


Okay now that I got that out of the way, as you can see the above function is pretty bloated.
We can use macros to hide some of the bloat of the class declaration like so:


#define nested(className) struct className { static

int main() {
nested(factClass) int factorial(int x) {
return (x <= 1) ? 1 : x * factorial(x-1);
}};

cout << factClass::factorial(5) << endl; // Prints '120'
return 0;
}


There's also another way to do this using functors.
Basically what we do is have a struct/class and then overload its "()" operator to make it look like a function call like so:


int main() {
struct {
int operator()(int x) {
return (x <= 1) ? 1 : x * this->operator()(x-1);
}
} factorial;

cout << factorial(5) << endl; // Prints '120'
return 0;
}



Now that's pretty cool.
We create an anonymous struct, and 'factorial' is an instance of that struct. Then it has the overloaded '()' operator which lets us call factorial(5) as if it was a function.

We can again use macros to hide some of the bloat, although the end result looks kind-of weird:


#define nested(xReturnType) struct { xReturnType operator()

int main() {
nested(int)(int x) {
return (x <= 1) ? 1 : x * this->operator()(x-1);
}} factorial;

cout << factorial(5) << endl; // Prints '120'
return 0;
}


The nice thing about using functors like in the last two examples is that you don't have to use a separate class name and function name (className::functionName()), instead you just use one name and call it with that name.

Anyways there you go, we have shown a variety of ways you can do nested functions, and I would stick to lambdas unless you're not using c++0x, in which you'll have to use one of the nested-class tricks mentioned above ;p

2 comments: