#include <iostream>
template<typename... T> using void_t = void;
template<typename T> struct TemporaryBindObject {};
namespace detail
{
template<typename... T> using void_t = void;
template<typename... T> struct TemporaryBindObject {};
template<template<typename...> class Dest, typename T, typename = void_t<>> struct toTypesOf
: std::false_type {};
template<template<typename...> class Dest, template<typename...> class Src, typename... Ts> struct toTypesOf<Dest, Src<Ts...>, void_t<Dest<Ts...>>>
: std::true_type {};
}
template<template<typename...> class Dest, typename... Ts>
using IsValidBind = typename detail::toTypesOf<Dest, detail::TemporaryBindObject<Ts...>>;
template<template<typename...> class Dest, typename... Ts>
using IsValidBindWithFloat = IsValidBind<Dest, Ts..., float>;
template<template<typename...> class Dest, typename... Ts>
using IsValidBindWithVoid = IsValidBind<Dest, Ts..., void>;
template<typename T> struct OneParamStruct{};
template<typename T1, typename T2> struct TwoParamStruct{};
int main()
{
std::cout << "Can bind to TwoParamStruct: " << IsValidBindWithFloat<TwoParamStruct, int>::value << std::endl;
std::cout << "Can bind to OneParamStruct: " << IsValidBindWithFloat<OneParamStruct, int>::value << std::endl;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgoKdGVtcGxhdGU8dHlwZW5hbWUuLi4gVD4gdXNpbmcgdm9pZF90ID0gdm9pZDsKCnRlbXBsYXRlPHR5cGVuYW1lIFQ+IHN0cnVjdCBUZW1wb3JhcnlCaW5kT2JqZWN0IHt9OwoKbmFtZXNwYWNlIGRldGFpbAp7Cgl0ZW1wbGF0ZTx0eXBlbmFtZS4uLiBUPiB1c2luZyB2b2lkX3QgPSB2b2lkOwoJCgl0ZW1wbGF0ZTx0eXBlbmFtZS4uLiBUPiBzdHJ1Y3QgVGVtcG9yYXJ5QmluZE9iamVjdCB7fTsKCQogICAgdGVtcGxhdGU8dGVtcGxhdGU8dHlwZW5hbWUuLi4+IGNsYXNzIERlc3QsIHR5cGVuYW1lIFQsIHR5cGVuYW1lID0gdm9pZF90PD4+IHN0cnVjdCB0b1R5cGVzT2YKICAgICAgICA6IHN0ZDo6ZmFsc2VfdHlwZSB7fTsKICAgIHRlbXBsYXRlPHRlbXBsYXRlPHR5cGVuYW1lLi4uPiBjbGFzcyBEZXN0LCB0ZW1wbGF0ZTx0eXBlbmFtZS4uLj4gY2xhc3MgU3JjLCB0eXBlbmFtZS4uLiBUcz4gc3RydWN0IHRvVHlwZXNPZjxEZXN0LCBTcmM8VHMuLi4+LCB2b2lkX3Q8RGVzdDxUcy4uLj4+PgogICAgICAgIDogc3RkOjp0cnVlX3R5cGUge307Cn0KCnRlbXBsYXRlPHRlbXBsYXRlPHR5cGVuYW1lLi4uPiBjbGFzcyBEZXN0LCB0eXBlbmFtZS4uLiBUcz4KdXNpbmcgSXNWYWxpZEJpbmQgPSB0eXBlbmFtZSBkZXRhaWw6OnRvVHlwZXNPZjxEZXN0LCBkZXRhaWw6OlRlbXBvcmFyeUJpbmRPYmplY3Q8VHMuLi4+PjsKCnRlbXBsYXRlPHRlbXBsYXRlPHR5cGVuYW1lLi4uPiBjbGFzcyBEZXN0LCB0eXBlbmFtZS4uLiBUcz4KdXNpbmcgSXNWYWxpZEJpbmRXaXRoRmxvYXQgPSBJc1ZhbGlkQmluZDxEZXN0LCBUcy4uLiwgZmxvYXQ+OwoKdGVtcGxhdGU8dGVtcGxhdGU8dHlwZW5hbWUuLi4+IGNsYXNzIERlc3QsIHR5cGVuYW1lLi4uIFRzPgp1c2luZyBJc1ZhbGlkQmluZFdpdGhWb2lkID0gSXNWYWxpZEJpbmQ8RGVzdCwgVHMuLi4sIHZvaWQ+OwoKdGVtcGxhdGU8dHlwZW5hbWUgVD4gc3RydWN0IE9uZVBhcmFtU3RydWN0e307CnRlbXBsYXRlPHR5cGVuYW1lIFQxLCB0eXBlbmFtZSBUMj4gc3RydWN0IFR3b1BhcmFtU3RydWN0e307CgppbnQgbWFpbigpCnsKICAgIHN0ZDo6Y291dCA8PCAiQ2FuIGJpbmQgdG8gVHdvUGFyYW1TdHJ1Y3Q6ICIgPDwgSXNWYWxpZEJpbmRXaXRoRmxvYXQ8VHdvUGFyYW1TdHJ1Y3QsIGludD46OnZhbHVlIDw8IHN0ZDo6ZW5kbDsKICAgIHN0ZDo6Y291dCA8PCAiQ2FuIGJpbmQgdG8gT25lUGFyYW1TdHJ1Y3Q6ICIgPDwgSXNWYWxpZEJpbmRXaXRoRmxvYXQ8T25lUGFyYW1TdHJ1Y3QsIGludD46OnZhbHVlIDw8IHN0ZDo6ZW5kbDsKfQ==