#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;
}
I2luY2x1ZGUgPHR5cGVfdHJhaXRzPgojaW5jbHVkZSA8dXRpbGl0eT4KI2luY2x1ZGUgPGlvc3RyZWFtPgoKdGVtcGxhdGU8dHlwZW5hbWUuLi4gVHM+CnN0cnVjdCB0eXBlbGlzdAp7fTsKCm5hbWVzcGFjZSBpbXBsCnsKICAgIHN0cnVjdCBzZmluYWVfcmVzdWx0e307CgogICAgdGVtcGxhdGU8dHlwZW5hbWUgRiAsIHR5cGVuYW1lIEFSR1MgLCB0eXBlbmFtZSBFTkFCTEVEID0gc2ZpbmFlX3Jlc3VsdD4KICAgIHN0cnVjdCBpc192YWxpZF9jYWxsOwoKICAgIHRlbXBsYXRlPHR5cGVuYW1lIEYgLCB0eXBlbmFtZS4uLiBBUkdTPgogICAgc3RydWN0IGlzX3ZhbGlkX2NhbGw8Rix0eXBlbGlzdDxBUkdTLi4uPiwKICAgICAgICAgICAgICAgICAgICAgICAgIGRlY2x0eXBlKCBzdGQ6OmRlY2x2YWw8Rj4oKShzdGQ6OmRlY2x2YWw8QVJHUz4oKS4uLikgKQogICAgICAgICAgICAgICAgICAgICAgICA+IDogCiAgICAgICAgcHVibGljIHN0ZDo6dHJ1ZV90eXBlCiAgICB7fTsKCiAgICB0ZW1wbGF0ZTx0eXBlbmFtZSBGICwgdHlwZW5hbWUuLi4gQVJHUz4KICAgIHN0cnVjdCBpc192YWxpZF9jYWxsPEYsdHlwZWxpc3Q8QVJHUy4uLj4sc2ZpbmFlX3Jlc3VsdD4gOiAKICAgICAgICBwdWJsaWMgc3RkOjpmYWxzZV90eXBlCiAgICB7fTsKfQoKdGVtcGxhdGU8dHlwZW5hbWUgRiAsIHR5cGVuYW1lLi4uIEFSR1M+CnN0cnVjdCBpc192YWxpZF9jYWxsIDogcHVibGljIGltcGw6OmlzX3ZhbGlkX2NhbGw8Rix0eXBlbGlzdDxBUkdTLi4uPj4Ke307Cgp2b2lkIGZvbyggaW50ICl7fQoKc3RydWN0IGJhciAKe307Cgpjb25zdGV4cHIgY29uc3QgYm9vbCBvayAgID0gaXNfdmFsaWRfY2FsbDxkZWNsdHlwZShmb28pLGludD46OnZhbHVlOwpjb25zdGV4cHIgY29uc3QgYm9vbCBub29rID0gaXNfdmFsaWRfY2FsbDxkZWNsdHlwZShmb28pLGJhcj46OnZhbHVlOwoKaW50IG1haW4oKQp7CglzdGQ6OmNvdXQgPDwgc3RkOjpib29sYWxwaGE7CglzdGQ6OmNvdXQgPDwgIm9rOiAiIDw8IG9rIDw8IHN0ZDo6ZW5kbDsKCXN0ZDo6Y291dCA8PCAibm9vazogIiA8PCBvayA8PCBzdGQ6OmVuZGw7Cn0=