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

如何实现IsAnyOfTypes概念以匹配包装结构体中的类型列表

实现基于自定义类型列表的IsAnyOfTypes概念

我使用如下自定义结构体实现类型列表的参数化:

template <typename... T>
struct types
{
};

通过它可以定义类似using MyTypes = types<int, double>的类型列表,并基于此生成其他关联类型。现在需要实现一个通用的IsAnyOfTypes概念,用于限定函数参数必须是该列表中的类型,期望能写出template <typename T> concept MyType = IsAnyOfTypes<T, ListOfTypes>这样的代码,且实现方式要像标准库的IsAnyOf那样简洁,避免递归模板和之前基于std::tuple的间接实现。

简洁实现方案

方式一:辅助模板偏特化 + 折叠表达式

通过偏特化提取types中的参数包,结合折叠表达式完成类型匹配判断:

#include <concepts>
#include <type_traits>

// 辅助模板,默认匹配为false
template<typename T, typename Types>
struct is_any_of_types_impl : std::false_type {};

// 偏特化匹配types<Ts...>,用折叠表达式判断类型是否存在
template<typename T, typename... Ts>
struct is_any_of_types_impl<T, types<Ts...>> 
    : std::bool_constant<(std::same_as<T, Ts> || ...)> {};

// 最终对外暴露的concept
template<typename T, typename Types>
concept IsAnyOfTypes = is_any_of_types_impl<T, Types>::value;

方式二:概念内直接模板推导(更紧凑)

无需额外辅助结构体,直接在概念中通过模板lambda推导展开类型列表:

#include <concepts>

template<typename T, typename Types>
concept IsAnyOfTypes = requires {
    // 推导types中的参数包,用折叠表达式完成匹配判断
    []<typename... Ts>(types<Ts...>) {
        return (std::same_as<T, Ts> || ...);
    }(std::declval<Types>());
};

使用示例

// 定义自定义类型列表
using MyTypes = types<int, double>;

// 基于IsAnyOfTypes定义专属concept
template<typename T>
concept MyType = IsAnyOfTypes<T, MyTypes>;

// 仅接受MyTypes列表中类型的函数
void process(MyType auto value) {
    // 函数逻辑
}

int main() {
    process(100);    // 合法:int属于MyTypes
    process(3.14);   // 合法:double属于MyTypes
    // process("test"); // 编译错误:const char*不在MyTypes中
}

这个实现完全贴合需求:没有递归模板,逻辑直接清晰,和标准库IsAnyOf的实现思路一致,仅增加了从自定义types结构体中提取参数包的步骤,避免了之前基于std::tuple的间接依赖。

内容的提问来源于stack exchange,提问作者TooTone

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 16:33:26