I have a templated function that invokes another function and stores its return value, then does some work before returning the value. I’d like to extend this to handle T = void, and was wondering if specialization is my only option.
template<typename T>
T Foo( T(*Func)() )
{
// do something first (e.g. some setup)
T result = Func();
// do something after (e.g. some tear down)
return result;
}
// Is this specialization the only option?
template<>
void Foo<void>( void(*Func)() )
{
// do something first (e.g. some setup)
Func();
// do something after (e.g. some tear down)
return;
}
void Bar() {}
int BarInt() { return 1; }
int main()
{
Foo<int>(&BarInt);
Foo<void>(&Bar);
}
Or can the regular version of Foo be modified to handle the void type and basically do nothing in that case? I was thinking that maybe my local result could be wrapped in a type that could handle void maybe, but could also see the assignment as being a deal-breaker.
Given that your operation does not depend on the result of the function, you can do it without a specialization. It is ok for a function returning
voidto return an expression of typevoid. So thereturnpart is not the troublesome one, but you need to figure out a way to do the pre and post operations. Constructors and destructors will help you there:Then you can write your function like this:
For a more general solution using lambdas as you commented, it could look like this:
A type-erased version using
std::function< void() >would be easier to write and use, but it would be rather inefficient.