Я хочу проверить, может ли шаблон быть специализированным с использованием заданного набора аргументов. Вот версия для шаблонов, принимающих только 1 аргумент:
#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;
}
Этот выполняет задание для шаблонов, принимающих только один аргумент, но, очевидно, я хочу иметь возможность использовать это с несколькими аргументами, поэтому я попробовал это:
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));
};
Теперь это то, где вещи становятся странными, потому что теперь значение всегда неверно.
Есть ли что-то, что мне не хватает? Что между этими двумя версиями так сильно отличается? Есть ли другой способ достичь этого?