#include <type_traits>
#include <utility>
#include <iostream>

template<typename... Ts>
struct typelist
{};

namespace impl
{
    struct sfinae_result{};

    template<typename F , typename ARGS , typename ENABLED = sfinae_result>
    struct is_valid_call;

    template<typename F , typename... ARGS>
    struct is_valid_call<F,typelist<ARGS...>,
                         decltype( std::declval<F>()(std::declval<ARGS>()...) )
                        > : 
        public std::true_type
    {};

    template<typename F , typename... ARGS>
    struct is_valid_call<F,typelist<ARGS...>,sfinae_result> : 
        public std::false_type
    {};
}

template<typename F , typename... ARGS>
struct is_valid_call : public impl::is_valid_call<F,typelist<ARGS...>>
{};

void foo( int ){}

struct bar 
{};

constexpr const bool ok   = is_valid_call<decltype(foo),int>::value;
constexpr const bool nook = is_valid_call<decltype(foo),bar>::value;

int main()
{
	std::cout << std::boolalpha;
	std::cout << "ok: " << ok << std::endl;
	std::cout << "nook: " << ok << std::endl;
}