这里去(未经测试):
template <typename HOOK, typename RET, typename... ARGS>
struct BeforeHook {
std::function<RET(ARGS...)> functor;
HOOK hook;
BeforeHook(blah) : blah {};
RET operator()(ARGS&&... args) const {
hook();
return functor(args...);
}
};
template <typename HOOK, typename RET, typename... ARGS>
BeforeHook<HOOK, RET, ARGS...> hook_before(const std::function<RET(ARGS...)> &original, HOOK hook) {
return BeforeHook<HOOK, RET, ARGS...>(original, hook);
}
用法:
auto hooked = hook_before(original_functor, hook_functor);
hooked(args_for_original_functor); // calls hook_functor, then original_functor
或类似的规定。original_functor 需要转换为std::function
,但几乎所有可调用的都是。两个仿函数都需要成本可调用,但如果您愿意,可以将其const
删除operator()
。
如果您想尝试返回 lambda 而不是 的实例,请对模板参数和BeforeHook
使用相同的技巧,并确定是否可以在 lambda 中使用模板参数包:RET
...ARGS
template <typename HOOK, typename RET, typename... ARGS>
std::function<RET(ARGS...)> hook_before(const std::function<RET(ARGS...)> &original, HOOK hook) {
return [=](ARGS&&... args) -> RET {
hook();
return original(args...);
};
}
无论哪种方式,我认为关键技巧是std::function
在模板参数推导中使用将返回类型与参数分开。