skip to content

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.