Your case for true_type test does not look right. Anyway, your code is more complicated than necessary. Try the following minimal working example:
#include <utility> template<typename F, typename...Args> struct is_callable { template<typename F2, typename...Args2> static constexpr std::true_type test(decltype(std::declval<F2>()(std::declval<Args2>()...)) *) { return {}; } template<typename F2, typename...Args2> static constexpr std::false_type test(...) { return {}; } static constexpr bool value = decltype(test<F, Args...>(nullptr))::value; }; void f0(); static_assert(is_callable<decltype(f0)>::value, "f0()"); static_assert(!is_callable<decltype(f0), int>::value, "f0(0)"); int f1(int); static_assert(!is_callable<decltype(f1)>::value, "f1()"); static_assert(is_callable<decltype(f1), int>::value, "f1(0)"); static_assert(!is_callable<decltype(f1), int, int>::value, "f1(0, 0)"); auto __attribute__((unused)) f2 = [](int, char *) { return 7; }; static_assert(is_callable<decltype(f2), int, char *>::value, "f2(int, char *)"); static_assert(!is_callable<decltype(f2), int, int>::value, "f2(int, int)");
source share