You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让元函数兼容带类型与非类型模板参数的模板

解决方案

问题核心是原模板模板参数仅支持纯类型参数的模板,而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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.29 19:22:06