C++ Local Functions Without Lambdas
C++ has no concept of local functions: functions defined in the scope of another function.
int main()
{
int foo() // defining
{ // local functions
return 0; // is not
} // valid C++
return foo();
}
C++11 adds support for lambda expressions:
int main()
{
auto foo = [] () { return 0; }; // non capturing lambda
return foo();
}
If you’re locked in pre-C++11, you’re not out of luck though. C++ always has allowed the definition of local types. Instead of a lambda, you can fall back to defining a struct
with a static
method:
int main()
{
struct local
{
static int foo()
{
return 0;
}
};
return local::foo();
}
This is a trick I’ve been using in production unit tests when testing C APIs that take callbacks. And yes we are (also) targeting non C++11 compilers:
TEST(ApiTest, doSomething())
{
struct ProgressState
{
ProgressState(bool returnValue = true)
: calls(0),
rate(0),
returnValue(returnValue)
{}
void reset()
{
calls = 0;
rate = 0;
}
static bool progress(uint32_t amountDone, uint32_t amountTodo, ProgressState* state)
{
if (state->calls == 0)
EXPECT_EQ(0, amountDone);
float rate = (float)amountDone / (float)amountTodo;
EXPECT_GE(rate, state->rate);
state->rate = rate;
++state->calls;
return state->returnValue;
}
int calls;
float rate;
bool returnValue;
};
ProgressState state;
EXPECT_TRUE(doSomething((ProgressFunc)ProgressState::progress, &state));
}
I learnt it a long time ago on the good old flipcode and at least Tom Forsyth mentioned it on Twitter recently.