I'm writing a C++ application and have abstracted a method over a lambda parameter. I originally used the following signature:
void atomically(void (*block)(T& value, bool& retry))
But I discovered that you cannot pass an arbitrary lambda as a function pointer -- the lambda must have no captures. I could use
void atomically(const std::function<void (T&, bool&)>& block)
Except it is very important in this part of the code that we avoid allocating on the heap, and creating an std::function
might allocate. (Are there guarantees about if/when it does?)
Finally, I could use:
template<class F>
void atomically(const F& block) {
// use block() as if it had been declared as above
}
Except I find this unacceptable as it allows block
to take its parameters by value instead of by reference, which would be an easy mistake to make and very subtle to debug.
What is the proper convention for taking a lambda as a parameter? Or, is there a way, in the final template solution, to ensure that block
gets its parameters by reference?