如何在测试多种类型与多个C++20概念时避免代码重复?
批量校验类型列表是否满足C++20概念的简洁实现
针对你提到的两处代码重复问题,可以通过通用化概念包装和类型列表复用彻底解决,以下是几种简洁的实现方案:
方案1:自定义类型列表+通用校验概念
先定义一个通用的all_satisfy_list概念,无需为每个基础概念单独编写可变参数版本;同时用轻量化的自定义type_list统一管理待校验类型,彻底避免重复输入类型列表:
#include <concepts> // 自定义轻量化类型列表模板 template <class... Ts> struct type_list {}; // 通用可变参数概念:检查所有输入类型都满足指定Concept template <template <class> typename Concept, class... Ts> concept all_satisfy = (Concept<Ts> && ...); // 辅助元函数:从type_list中提取类型并应用校验逻辑 template <template <class> typename Concept, class List> struct all_satisfy_list_impl; template <template <class> typename Concept, class... Ts> struct all_satisfy_list_impl<Concept, type_list<Ts...>> { static constexpr bool value = all_satisfy<Concept, Ts...>; }; // 包装成可直接使用的概念 template <template <class> typename Concept, class List> concept all_satisfy_list = all_satisfy_list_impl<Concept, List>::value; // 你的业务概念定义 template <class T> concept is_foo = std::destructible<T>; template <class T> concept is_bar = std::integral<T>; // 统一定义待校验的类型列表 using my_types = type_list<char, int>; int main() { static_assert(all_satisfy_list<is_foo, my_types>); static_assert(all_satisfy_list<is_bar, my_types>); return 0; }
方案2:基于std::tuple的简化实现
如果不想自定义type_list,可以直接用std::tuple作为类型容器,结合C++20的模板lambda简化类型展开逻辑:
#include <concepts> #include <tuple> // 通用概念:检查std::tuple中的所有类型都满足指定Concept template <template <class> typename Concept, class Tuple> concept all_satisfy_tuple = []<class... Ts>(std::tuple<Ts...>) { return (Concept<Ts> && ...); }(std::declval<Tuple>()); // 你的业务概念定义 template <class T> concept is_foo = std::destructible<T>; template <class T> concept is_bar = std::integral<T>; // 用std::tuple作为类型列表 using my_types = std::tuple<char, int>; int main() { static_assert(all_satisfy_tuple<is_foo, my_types>); static_assert(all_satisfy_tuple<is_bar, my_types>); return 0; }
方案3:宏进一步简化调用语法
如果需要更精简的校验语句,可以用宏封装重复的static_assert逻辑:
#include <concepts> // (复用方案1中的type_list、all_satisfy_list等定义) #define CHECK_CONCEPT(Concept, TypeList) static_assert(all_satisfy_list<Concept, TypeList>) int main() { CHECK_CONCEPT(is_foo, my_types); CHECK_CONCEPT(is_bar, my_types); return 0; }
核心优势
- 彻底消除了“每个概念对应一个all_are_x”的重复代码,通用校验逻辑只需编写一次
- 类型列表仅需定义一次,所有校验共享同一列表,避免重复输入类型
- 支持任意数量的概念和类型,扩展时只需新增概念或修改类型列表
内容的提问来源于stack exchange,提问作者akerstjens
相关产品推荐
相关产品推荐

