I’m wondering why std::invoke cannot infer that X below has an operator with signature below vs. having the requirement to specify the pointer to member function explicitly. The latter makes std::invoke more generally applicable but are there rules that would prevent the special case from being deduced.
#include <functional>
struct X {
void operator()() {
}
};
void call(X *ptr) {
// std::invoke(ptr); // Does not compile
std::invoke(&X::operator(), ptr); // Works
}
>Solution :
In the code, you posted, std::invoke cannot infer the correct pointer to the member function because you are passing a pointer to an object of type X rather than an object of type X itself. std::invoke expects its first argument to be a callable object or a pointer to a member function, but a pointer to an object is not the same as a callable object or a pointer to a member function.
In order to use std::invoke with a pointer to an object, you can first dereference the pointer to obtain a reference to the object, and then pass that reference as the first argument to std::invoke. For example:
#include <functional>
struct X {
void operator()() {
}
};
void call(X *ptr) {
std::invoke(*ptr); // Works
}
This code will compile and work as expected because std::invoke is now able to infer that a first argument is a callable object of type X, and it can therefore use the operator() of that object to call the function.