C++如何实现支持混合类型与非类型参数包的特化检测trait
解决方案
C++20 及以上版本
C++20 扩展了模板模板参数的匹配规则,允许使用 auto... 作为形参列表接收任意混合类型、非类型、模板类型的参数,直接修改特化声明即可实现全场景覆盖:
template <typename T> struct is_specialisation : std::false_type {}; // 匹配任意参数类型的模板特化 template <template <auto...> class U, auto... Args> struct is_specialisation<U<Args...>> : std::true_type {}; // 可选:补充匹配参数为模板类型的特化场景 template <template <template <typename...> class...> class U, template <typename...> class... Args> struct is_specialisation<U<Args...>> : std::true_type {};
修改后所有测试用例均可正常匹配:
is_specialisation<std::vector<int>>::value; // true is_specialisation<std::string_view>::value; // true is_specialisation<std::tuple<char, int, double>>::value; // true is_specialisation<std::array<char, 4>>::value; // true is_specialisation<float>::value; // false
C++17 及更低版本兼容方案
如果编译环境不支持 C++20,可以通过多组特化覆盖常见的参数组合场景,足够覆盖绝大多数日常开发需求:
// 主模板 template <typename T> struct is_specialisation : std::false_type {}; // 特化1:全类型参数的模板 template <template <typename...> class U, typename... Args> struct is_specialisation<U<Args...>> : std::true_type {}; // 特化2:全非类型参数的模板 template <template <auto...> class U, auto... Args> struct is_specialisation<U<Args...>> : std::true_type {}; // 特化3:1个类型+1个非类型的常见组合(适配std::array等场景) template <template <typename, auto> class U, typename T1, auto V2> struct is_specialisation<U<T1, V2>> : std::true_type {}; // 可按需补充更多混合参数数量的特化,比如2类型+1非类型等
内容的提问来源于stack exchange,提问作者cmannett85
相关产品推荐
相关产品推荐

