我已经四处寻找了一段时间,但找不到我正在寻找的答案 - this question这可能是最接近我的想法的。
一句话:是否可以声明一个接受 std::function
参数的模板函数,并推导出函数的返回类型和参数类型的模板参数?示例:
//this works to pass the std::function in
template<class T>
void doSomething(std::function<T> f) {
f();
}
//this is more what i am looking for - can R and P be deduced automatically - does not work!
template<class R, class P>
void doSomethingElse(std::function<R(P)> f) {
f();
}
这是因为函数签名或函数类型本身被认为是一件事,因此不能“分解”?我意识到有 decltype
和 std::result_of
但无法想象我如何在这里使用它们。
作为补充一点,我如何使用可变参数模板扩展第二个示例以具有多个参数和推导?
最佳答案
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 和 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)
因此您可以在其中使用返回类型和参数类型。
关于c++ - 从作为模板函数参数传递的 std::function 推断返回和参数类型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55520170/