如何实现匹配任意指定Concept的C++概念并解决编译错误?
解决方案:实现匹配任意指定Concept的
any_of_c概念 问题背景
已定义以下C++20 Concept:
#include <type_traits> #include <string> template <typename type_t> concept boolean_c = std::is_same_v<std::decay_t<type_t>, bool>; template <typename type_t> concept integer_c = !boolean_c<type_t> && std::is_integral_v<std::decay_t<type_t>>; template <typename type_t> concept number_c = std::is_floating_point_v<std::decay_t<type_t>>; template <typename type_t> concept string_c = std::is_same_v<std::decay_t<type_t>, std::string>;
需要实现any_of_c概念,用于判断给定类型是否匹配指定列表中的任意一个Concept,并基于它实现compatible_type_c,最终扩展到检查std::tuple和std::variant的所有元素是否符合要求。
原尝试代码编译报错,错误信息:
<source>:17:45: error: expected ')' concept any_of_c = (concept_pack<type_t> || ...); ^ <source>:17:20: note: to match this '(' concept any_of_c = (concept_pack<type_t> || ...); ^ <source>:17:49: error: expected expression concept any_of_c = (concept_pack<type_t> || ...); ^ <source>:20:46: error: too few template arguments for concept 'boolean_c' concept compatible_type_c = any_of_c<type_t, boolean_c, integer_c, number_c, string_c>;;
错误原因
原代码的核心问题是模板模板参数的声明类型不匹配:
- 原代码使用
template<typename> class ... concept_pack作为模板参数,但boolean_c等是C++20 Concept,不是普通模板类,因此无法匹配。 - 必须将模板模板参数声明为
template<typename> concept ...才能接受Concept作为实参。
正确实现代码
1. 通用any_of_c概念
// 修正后的any_of_c:模板模板参数使用concept声明 template <typename type_t, template <typename> concept ... concept_pack> concept any_of_c = (concept_pack<type_t> || ...); // 基于any_of_c实现compatible_type_c template <typename type_t> concept compatible_type_c = any_of_c<type_t, boolean_c, integer_c, number_c, string_c>;
2. 扩展到std::tuple和std::variant的检查
如果需要检查std::tuple的所有元素、std::variant的所有备选类型都满足compatible_type_c,可以实现以下Concept:
#include <tuple> #include <variant> // 检查std::tuple的所有元素都符合指定Concept template <typename Tuple, template <typename> concept C> concept tuple_all_compatible = requires(Tuple) { // 利用模板lambda和折叠表达式约束所有元素类型 []<typename... Ts>(std::tuple<Ts...>) requires (C<Ts> && ...) {}(std::declval<Tuple>()); }; // 检查std::variant的所有备选类型都符合指定Concept template <typename Variant, template <typename> concept C> concept variant_all_compatible = requires(Variant) { []<typename... Ts>(std::variant<Ts...>) requires (C<Ts> && ...) {}(std::declval<Variant>()); }; // 针对compatible_type_c的专用检查 template <typename T> concept compatible_tuple = tuple_all_compatible<T, compatible_type_c>; template <typename T> concept compatible_variant = variant_all_compatible<T, compatible_type_c>;
使用示例
// 合法类型示例 static_assert(compatible_type_c<bool>); static_assert(compatible_type_c<int>); static_assert(compatible_type_c<double>); static_assert(compatible_type_c<std::string>); // 合法tuple示例 static_assert(compatible_tuple<std::tuple<bool, int, std::string>>); // 合法variant示例 static_assert(compatible_variant<std::variant<double, std::string>>); // 非法类型示例 static_assert(!compatible_type_c<char*>); static_assert(!compatible_tuple<std::tuple<bool, char*>>);
内容的提问来源于stack exchange,提问作者PaperBirdMaster
相关产品推荐
相关产品推荐

