I would like to create a compile-type function that, given any callable object f
(function, lambda expression, function object, ...) and a type T
,
A variant of Paul's answer, but following the standard SFINAE test pattern. Again a generic trait with arbitrary parameter types A...
:
struct can_call_test
{
template
static decltype(std::declval()(std::declval()...), std::true_type())
f(int);
template
static std::false_type
f(...);
};
template
using can_call = decltype(can_call_test::f(0));
Then a constexpr
function as you requested:
template
constexpr bool is_callable_with(F&&) { return can_call{}; }
Check live example.
This will work with functions, lambda expressions, or function objects with arbitrary number of arguments, but for (pointers to) member functions you'll have to use std::result_of
.
UPDATE
Below, can_call
has the nice "function signature" syntax of std::result_of
:
template
struct can_call : decltype(can_call_test::f(0)) { };
template
struct can_call : can_call { };
to be used like this
template
constexpr can_call
is_callable_with(F&&) { return can_call{}; }
where I've also made is_callable_with
variadic (I can't see why it should be limited to one argument) and returning the same type as can_call
instead of bool
(thanks Yakk).
Again, live example here.