template<class R, class P>
void doSomethingElse(std::function<R(P)> f) {
f(P{});
}
会起作用,但只有当你通过了std::function
到该函数,并且该函数有一个非 void 参数。但这是一种限制。您可以使用
template<class R, class... Args, class... Ts>
void doSomethingElse(std::function<R(Args...)> f, Ts&&... args) {
f(std::forward<Args>(args)...);
}
这将需要任何std::function
以及它的参数并调用它们,就像您在调用站点中所做的那样。但这仍然是有限的,因为调用站点要求您使用std::function
所以你不能向它传递任何可隐式转换为std::function
.
使用 C++17 和类模板参数推导 https://en.cppreference.com/w/cpp/language/class_template_argument_deduction(CTAD) 但这不再是问题了。我们可以创建一个采用任何类型的重载,然后使用 CTAD 构造一个 std::function 来为我们填充类型。那看起来像
template<class Func, class... Args>
void doSomethingElse(Func&& f, Args&&... args) {
doSomethingElse(std::function{std::forward<Func>(f)}, std::forward<Args>(args)...);
}
template<class R, class... Args, class... Ts>
void doSomethingElse(std::function<R(Args...)> f, Ts&&... args) {
f(std::forward<Args>(args)...);
}
现在任何不是std::function
将会去void doSomethingElse(Func&& f, Args&&... args)
,转换为std::function
,并传递给void doSomethingElse(std::function<R(Args...)> f, Args&&... args)
所以您可以在其中使用返回类型和参数类型。