根据文档,上面写着:
一个可调用类型是一个调用操作(由例如,std::function, std::bind, std::thread::thread) is适用。方法显式执行此操作标准库函数std::invoke。(因为c++ 17)
需求类型T满足Callable if Given f,一个类型为T的对象参数类型R,
的合适列表表达式必须有效:
std::declval()…)中的表达式格式良好调用(f,合适的返回类型)
问题1:
如果我理解正确,给定void foo(int) {}
,std::function(foo)
是不可调用的,而std::function(foo, 1)
是可调用的。我说的对吗?
问题2:让我困惑的是下面的语句。
根据文件,上面说[强调我的]:
如你所见,类模板std::packaged_task包装了任何可调用的目标,类模板std::packaged_task包装任何Callable目标(函数、lambda表达式、绑定表达式或其他函数对象),以便可以异步调用它。其返回值或抛出的异常存储在可访问的共享状态中通过std::future对象。
std::function{foo}
不可调用,但std::packged_task<void(int)> task{f};
可以编译。
如果一个人想成为一名成功的专业人士,他们不会停止阅读介绍部分的文章。如果他们继续阅读文章和参考文章,他们会在那里找到所有的答案。
你的第一个问题直接在那一页得到了回答:
- 否则,
INVOKE(f, t1, t2, ..., tN)
相当于f(t1, t2, ..., tN)
(即f是一个FunctionObject)。
打开引用:
FunctionObjectType是可在函数调用操作符左侧使用的对象类型。
因此,void foo(int) {}
是可调用的。std::function(foo)
和std::function(foo, 1)
都不能编译。我猜你是指std::function f(foo)
,或std::function f{foo}
,或std::function<void(int)> f(foo)
,这两个显然是可调用的,我猜你混淆了std::bind(foo, 1)
和std::function(foo, 1)
,这也是可调用的。
你现在知道为什么std::packged_task<void(int)> task{f};
是编译的了——因为f
是可调用的。