如何限制C++模板参数包仅接受int32_t和std::string类型?
实现模板参数包限制为指定多种类型
要让模板参数包Ts...中的每个类型都只能是int32_t或std::string,可以用以下两种直观的方式实现:
方法一:自定义类型判断Trait
先定义一个辅助Trait,用来检查单个类型是否属于允许的范围,再通过std::conjunction_v确保所有参数都满足该条件:
#include <type_traits> #include <cstdint> #include <string> template<typename T> struct is_allowed_type : std::disjunction<std::is_same<T, int32_t>, std::is_same<T, std::string>> {}; template<typename T> constexpr bool is_allowed_type_v = is_allowed_type<T>::value; template<typename... Ts> std::enable_if_t<std::conjunction_v<is_allowed_type<Ts>...>> send(bool condition, Ts...);
方法二:直接在enable_if内展开判断
你之前的写法无法编译,是因为不能直接在参数包展开中使用||运算符,需要把每个类型的判断逻辑包装成std::disjunction,再通过std::conjunction_v统一校验所有参数:
#include <type_traits> #include <cstdint> #include <string> template<typename... Ts> std::enable_if_t<std::conjunction_v<std::disjunction<std::is_same<Ts, int32_t>, std::is_same<Ts, std::string>>...>> send(bool condition, Ts...);
这种写法无需额外定义Trait,直接在enable_if中完成所有约束逻辑,代码更紧凑。
关于variant临时方案的说明
用std::is_assignable配合std::variant的方式确实能实现需求,但存在语义不直观的问题——其他开发者阅读代码时需要额外理解allowed_types的作用,且如果允许的类型包含不可拷贝/移动的类型,该方案可能会出现异常。上面两种方法更直接,也更贴合模板参数约束的语义。
内容的提问来源于stack exchange,提问作者mincequi
相关产品推荐
相关产品推荐

