[英]Check if valid template specialization
我想检查一个模板是否可以使用给定的参数集进行专门化。 以下是仅接受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));
};
现在这就是事情变得奇怪的地方,因为现在价值总是假的 。
有什么我想念的吗? 这两个版本之间有什么完全不同? 还有另一种方法来实现这一目标吗?
以下更容易,有效:
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));
};
即使您明确指定了第一个T ...参数,功能测试(U ...)接受的模板参数的数量仍然是未知的。 可以从函数参数推导出额外的U ...模板参数。 由于函数参数(0)无助于猜测U ...的大小,因此第一个模板函数未实例化。 重要的是要注意模板参数D也可以采用任意数量的参数。 编译器不应该做任何假设。
GCC和Clang是对的。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.