I want to check whether or not a template can be specialized using a given set of arguments. Here is the version for templates accepting only 1 argument:
#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;
}
This does the job for templates accepting only a single argument, but obviously I want to be able to use this with multiple arguments as well, so I tried this:
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));
};
Now this is where things get weird, because now value is always false.
Is there something I'm missing? What is so utterly different between these two versions? Is there another way to achieve this?
EDIT:
I've filed a bug report for both Clang and GCC
The following is easier and works:
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>
static yes test(D<T...>*);
template<template<typename...> class D>
static no test(...);
constexpr static bool value = (sizeof(test<C>(0)) == sizeof(yes));
};
Live example
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With