检查是否有效的模板专业化

Tom*_*pen 14 c++ templates sfinae variadic-templates c++11

我想检查一个模板是否可以使用给定的参数集进行专门化.以下是仅接受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;
}
Run Code Online (Sandbox Code Playgroud)

这样做的模板只接受一个参数,但显然我希望能够将它与多个参数一起使用,所以我尝试了这个:

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));
};
Run Code Online (Sandbox Code Playgroud)

现在这就是事情变得奇怪的地方,因为现在价值总是假的.

有什么我想念的吗?这两个版本之间有什么完全不同?还有另一种方法来实现这一目标吗?

编辑:
我已经为ClangGCC提交了一份错误报告

Dan*_*rey 9

以下更容易,有效:

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));
};
Run Code Online (Sandbox Code Playgroud)

实例

  • 两个[原创](http://rextester.com/live/MIIMG71382)和[modified](http://rextester.com/live/VMKOG37148)代码在Visual C++上编译得很好(除了`constexpr`关键字,课程).使用`std :: true_type`,`std :: false_type`和`std :: is_same`可以简化这些代码. (3认同)