I am trying to write a templated wrapper class around a stateless lambda. Something like this:
template <class TFuncOp>
class Adapter
{
public:
void Op()
{
TFuncOp func; // not possible before C++20
func();
}
};
Since this isn't possible before default constructible lambdas arrive with C++20, I used this technique to make my class work: Calling a stateless lambda without an instance (only type)
So the final solution looks like this:
template <class TFuncOp>
class Adapter
{
public:
static TFuncOp GetOpImpl( TFuncOp *pFunc = 0 )
{
static TFuncOp func = *pFunc;
return func;
}
void Op()
{
GetOpImpl()();
}
};
template <class TFuncOp>
Adapter<TFuncOp> MakeAdapter(TFuncOp func )
{
// Removing the line below has no effect.
//Adapter<TFuncOp>::GetOpImpl( &func );
return Adapter<TFuncOp>();
}
int main()
{
auto adapter = MakeAdapter( [] { printf("Hello World !\n"); } );
adapter.Op();
return 0;
}
This code works on all major compilers (clang, gcc, msvc). But with one surprising discovery. Initialization (or lack thereof) of the static local instance of the lambda in GetOpImpl() has no effect. It works fine either way.
Can anyone explain how this works? Am I invoking UB if I use the static local instance of the lambda without initializing it?