You could do:
template<class R, class... Args> struct FnBase { virtual R operator()(Args...) = 0; }; class MyThread : FnBase<void> { ... };
This is pithy and clever, but in exchange makes the code less obviously self-documenting (implementation details creeping into type declarations) and complicates implementing multiple interfaces on the same receiver.
This is pithy and clever, but in exchange makes the code less obviously self-documenting (implementation details creeping into type declarations) and complicates implementing multiple interfaces on the same receiver.