Basically, what I want to achieve is compile-time verification (with possibly nice error message) that registered callable (either a function, a lambda, a struct with call o
In C++17 there is trait is_invocable, which does exactly what you ask for. Its advantage over is_convertible is that you don't have to specify return type.
It might sound like overkill but recently I had problem that had to use it, exactly my wrapper function deduced its return type from passed Callable, but I've passed templated lambda like this one [](auto& x){return 2*x;}, so return type of it was deduced in subcall. I couldn't convert it into std::function and I ended up using local implementation of is_invocable for C++14. I cannot find the link where I got it from though... Anyway, the code:
template
struct is_invocable
{
template
static auto test(U* p) -> decltype((*p)(std::declval()...), void(), std::true_type());
template
static auto test(...) -> decltype(std::false_type());
static constexpr bool value = decltype(test(0))::value;
};
and for your example:
struct A {
using Signature = void(int, double);
template
void Register(Callable &&callable) {
static_assert(is_invocable::value, "not foo(int,double)");
callback = callable;
}
std::function callback;
};