如何让元函数兼容带类型与非类型模板参数的模板
解决方案
问题核心是原模板模板参数仅支持纯类型参数的模板,而entity包含非类型模板参数(std::size_t N),导致类型匹配失败。要兼容混合类型/非类型模板参数,需利用C++20的模板模板参数占位符特性,调整实现逻辑:
修改后的完整代码
#include <chrono> #include <vector> #include <cstdio> #include <type_traits> // 基础模板:默认返回false template <template <auto...> class, typename> struct is_specialization : std::false_type {}; // 特化版本:匹配任意模板参数(类型/非类型)的模板特化 template <template <auto...> class Template, auto... Args> struct is_specialization<Template, Template<Args...>> : std::true_type {}; // Concept定义:接收模板和待检测类型,由特化模板推导参数 template <template <auto...> class Template, typename T> concept is_specialization_of = is_specialization<Template, T>::value; template <std::size_t N, typename A> struct entity { }; template <typename T> requires is_specialization_of<entity, T> struct other { other(const T& e) : e_{ e } { } T e_; }; int main() { // 现在可正常编译 other o{entity<2, int>()}; // 纯类型模板场景依然兼容 std::vector<int> vec; if constexpr (is_specialization_of<std::vector, decltype(vec)>) { printf("Hello!\n"); } }
关键修改点
- 模板模板参数改为
auto...:C++20起允许用auto...作为模板模板参数的占位符,支持匹配类型、非类型甚至模板类型的参数,不再局限于typename...。 - 调整Concept参数逻辑:原Concept的
Args...属于冗余设计,只需传入待检测类型T,由特化模板自动推导目标模板的参数。 - 特化模板适配混合参数:特化版本中的
Args...为auto...类型,能同时匹配非类型参数(如std::size_t)和类型参数(如int)。
修改后,is_specialization_of可同时处理纯类型模板(如std::vector)和含非类型参数的模板(如entity)。
内容的提问来源于stack exchange,提问作者glades
相关产品推荐
相关产品推荐

