As per the document, which says:
A Callable type is a type for which the INVOKE operation (used by, e.g., std::function, std::bind, and std::thread::thread) is applicable. This operation may be performed explicitly using the library function std::invoke. (since C 17)
Requirements
The type T satisfies Callable if Given f, an object of type T ArgTypes, suitable list of argument types R,
expressions must be valid:
std::declval()...) the expression is well-formed in unevaluated contextExpression Requirements INVOKE(f,suitable return type The following
Question 1:
If I understand correctly, given void foo(int) {}
, std::function(foo)
is not callable, whereas std::function(foo, 1)
is callable. Am I right?
Question 2: What confuses me is the statement below.
As per the document, which says[emphasis mine]:
The class template std::packaged_task wraps any Callable target (function, lambda expression, bind expression, or another function object) so that it can be invoked asynchronously. Its return value or exception thrown is stored in a shared state which can be accessed through std::future objects.
As you see that the class template std::packaged_task wraps any Callable target, and std::function{foo}
is not callable, but std::packged_task<void(int)> task{f};
compiles.
CodePudding user response:
If one wants to be a successful professional, they do not stop reading the article on the introduction. If they continue reading the article and the referenced articles, they find all answers there.
Your first question is answered directly on that page:
- otherwise,
INVOKE(f, t1, t2, ..., tN)
is equivalent tof(t1, t2, ..., tN)
(that is, f is a FunctionObject).
Opening the reference:
A FunctionObject type is the type of an object that can be used on the left of the function call operator.
Therefore, void foo(int) {}
is callable. The both std::function(foo)
and std::function(foo, 1)
will not compile. I guess you mean std::function f(foo)
, or std::function f{foo}
, or std::function<void(int)> f(foo)
, the both are obviously callable, and I guess you confused std::bind(foo, 1)
with std::function(foo, 1)
, that is also callable.
You know now, why std::packged_task<void(int)> task{f};
is compiled - because f
is callable as it is figured out above.
CodePudding user response:
A callable is literally anything you can call, either because its a function, a function pointer, or because it overloads operator()
regardless of how many arguments it has. Here's an example of all three:
void foo(int) {} // callable
int main() {
auto fp = foo; // callable
auto foo2 = [] { foo(42); }; // callable
}