[英]How to use std::function using variadic template
template< class R, class... Args >
class function<R(Args...)>;
我还没弄明白如何调用它。 (VC ++,如果重要的话。)
问题:如何在不使用std::bind
情况下将std::bind
std::function
与variadic列表一起使用?
#include <functional>
#include <iostream>
using vfunc = std::function<void()>;
using namespace std; // I know, I know.
template<class F, class... Args>
void
run(F&& f, Args&&... args) {
vfunc fn = bind(forward<F>(f), forward<Args>(args)...); //OK
//vfunc fn = vfunc(forward<F>(f), forward<Args>(args)...); // COMPILER ERROR
fn();
}
void foo(int x) {
cout << x << " skidoo\n";
}
int main() {
run(foo, 23);
return 0;
}
有一个用于构造
std::function
的模板。template< class R, class... Args > class function<R(Args...)>;
这不是宣言的意思。 它没有声明构造函数或“构造”任何东西的模板; 它是模板类std::function
。 专门化是std :: function的唯一定义; 永远不会定义基本模板。 我认为这与在模板声明中使用函数签名有关。 也就是说,能够通过函数而不是函数来使用模板。
您希望获取可调用对象和一些值,并创建一个新的可调用对象来存储这些值,这些值具有一个operator()
重载,该重载使用这些值调用给定函数。 std::function
不这样做; 它没有这样做的构造函数。
这正是 std::bind
的用途。 基本上,你的代码很好:在function
存储bind
的结果是完全有效的。
在这种情况下,您可以将函数包装在lambda中并从中构造std::function
。
template<class F, class... Args>
void run(F&& f, Args&&... args) {
auto fn = vfunc{
[=]() mutable {
std::invoke(std::forward<F>(f), std::forward<Args>(args)...);
}
};
fn(); // fn is of type std::function<void()>
}
我让lambda变得可变,所以std::forward
不会默默地不动。
但请注意, [=]
捕获将复制所有内容。 要支持仅移动类型,您可以使用元组:
[f = std::forward<F>(f), args = std::tuple{std::forward<Args>(args)...}]() mutable {
std::apply(std::forward<F>(f), std::move(args));
}
在C ++ 20中,这变得更容易:
[f = std::forward<F>(f), ...args = std::forward<Args>(args)...]() mutable {
std::invoke(std::forward<F>(f), std::forward<Args>(args)...);
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.