Since 2017-03-13 std::is_callable is gone from cppreference.com. The last available description of it is from 2016-11-21 on WaybackMachine.
The main difference between std::is_callable and std::is_invocable, that replaced it, is that
- the former used a single template parameter
template <class FnArgs>specialized toFnArgs=Fn(Args...)for the callable typeFnand for the parameter types to test (Args...), while - the latter accepts all of these in separate template parameters (
template <class Fn, class... Args>).
What was the problem with std::is_callable's Fn(Args...) approach?
I understand, that Fn(Args...) is a function type, where Fn is the return type. std::is_callable gave Fn another meaning, the function type to test, which I find misleading. This is only one problem. Could you name all the rest?
What I can think of, but cannot put it together (in keywords):
- Not every type can be return or parameter type of a function, e.g.
void, abstract classes, C arrays, function types, abominable function types, incomplete types come to mind. - In function parameters array and function types decay into pointers (C++23 [dcl.fct]#5), and the top-level cv-qualifiers are discarded (C++23 [dcl.fct]#5).
- I don't know, maybe the
Fn(Args...)approach may introduce ambiguity in some cases. - Changing
Fn(Args...)to separate template parameters was proposed in LWG2895.
I have found one compiler on Godbolt, on which std::is_callable works: MVSC v19.10. The others say there is no such type in namespace std. Seeing it work helps to understand this type trait more deeply, e.g. Alisdair Meredith's example from P0604r0. See on Godbolt.
This can be answered from P0604 (which renamed
is_callable) bullet 3 that states: