#include <iostream>
template<template<typename...> class C, typename... T>
struct is_valid_specialization {
typedef struct { char _; } yes;
typedef struct { yes _[2]; } no;
template<template<typename...> class D, typename... U>
static yes test(D<U...>*);
template<template<typename...> class D, typename... U>
static no test(...);
constexpr static bool value = (sizeof(test<C, T...>(0)) == sizeof(yes));
};
template<typename T>
struct Test1 { };
template<typename T1, typename T2>
struct Test2 { };
template<typename...>
struct TestV { };
int main() {
std::cout << "Test1<T>: " << is_valid_specialization<Test1, int>::value << std::endl;
std::cout << "Test2<T>: " << is_valid_specialization<Test2, int>::value << std::endl;
std::cout << "TestV<T>: " << is_valid_specialization<TestV, int>::value << std::endl;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgoKdGVtcGxhdGU8dGVtcGxhdGU8dHlwZW5hbWUuLi4+IGNsYXNzIEMsIHR5cGVuYW1lLi4uIFQ+CnN0cnVjdCBpc192YWxpZF9zcGVjaWFsaXphdGlvbiB7Cgl0eXBlZGVmIHN0cnVjdCB7IGNoYXIgXzsgfSB5ZXM7Cgl0eXBlZGVmIHN0cnVjdCB7IHllcyBfWzJdOyB9IG5vOwoKCXRlbXBsYXRlPHRlbXBsYXRlPHR5cGVuYW1lLi4uPiBjbGFzcyBELCB0eXBlbmFtZS4uLiBVPgoJc3RhdGljIHllcyB0ZXN0KEQ8VS4uLj4qKTsKCXRlbXBsYXRlPHRlbXBsYXRlPHR5cGVuYW1lLi4uPiBjbGFzcyBELCB0eXBlbmFtZS4uLiBVPgoJc3RhdGljIG5vIHRlc3QoLi4uKTsKCgljb25zdGV4cHIgc3RhdGljIGJvb2wgdmFsdWUgPSAoc2l6ZW9mKHRlc3Q8QywgVC4uLj4oMCkpID09IHNpemVvZih5ZXMpKTsKfTsKCnRlbXBsYXRlPHR5cGVuYW1lIFQ+CnN0cnVjdCBUZXN0MSB7IH07Cgp0ZW1wbGF0ZTx0eXBlbmFtZSBUMSwgdHlwZW5hbWUgVDI+CnN0cnVjdCBUZXN0MiB7IH07Cgp0ZW1wbGF0ZTx0eXBlbmFtZS4uLj4Kc3RydWN0IFRlc3RWIHsgfTsKCmludCBtYWluKCkgewoJc3RkOjpjb3V0IDw8ICJUZXN0MTxUPjogIiA8PCBpc192YWxpZF9zcGVjaWFsaXphdGlvbjxUZXN0MSwgaW50Pjo6dmFsdWUgPDwgc3RkOjplbmRsOwoJc3RkOjpjb3V0IDw8ICJUZXN0MjxUPjogIiA8PCBpc192YWxpZF9zcGVjaWFsaXphdGlvbjxUZXN0MiwgaW50Pjo6dmFsdWUgPDwgc3RkOjplbmRsOwoJc3RkOjpjb3V0IDw8ICJUZXN0VjxUPjogIiA8PCBpc192YWxpZF9zcGVjaWFsaXphdGlvbjxUZXN0ViwgaW50Pjo6dmFsdWUgPDwgc3RkOjplbmRsOwp9