如何用C++20概念定义元素均满足约束的boost::hana::Sequence
更简洁地定义C++20概念
sequence_of_callables 背景与需求
我们已经有以下C++20概念及依赖定义:
#include <boost/hana.hpp> #include <iostream> namespace hana = boost::hana; // 仅为一致性定义 template <typename S> concept hana_sequence = hana::Sequence<S>::value; template <typename T> concept callable_with_int = requires(T&& t, int i) { t(i); };
我们需要定义sequence_of_callables概念,要求它同时满足两个条件:
- 属于
hana_sequence类型 - 序列中的所有元素都满足
callable_with_int概念
现有实现依赖冗余的辅助模板,我们可以通过更直接的方式实现该概念,无需额外辅助结构。
直接实现方式
方式一:使用hana::fold遍历检查所有元素类型
template <typename S> concept sequence_of_callables = hana_sequence<S> && hana::fold(hana::types_c<S>, true, []<typename T>(bool accumulator, hana::type<T>) { return accumulator && callable_with_int<T>; });
方式二:使用hana::all_of简化逻辑
template <typename S> concept sequence_of_callables = hana_sequence<S> && hana::all_of(hana::types_c<S>, []<typename T>(hana::type<T>) { return callable_with_int<T>; });
验证与使用
定义好概念后,原有的函数和测试代码可以正常工作:
void applyCallable(const sequence_of_callables auto& ha, int i) { hana::for_each(ha, [&] (auto e) {std::cerr<<"inside apply – "; e(i);}); } int main() { applyCallable(hana::make_tuple( [] (int i) {std::cerr<<"inside lambda0 "<<2*i<<"!\n";}, [] (int i) {std::cerr<<"inside lambda1 "<<i<<"!\n";}/*, [] () {std::cerr<<"inside lambda2!\n";}*/ // 取消注释会触发编译失败,符合预期 ),4); }
说明
两种实现方式都直接在概念的布尔表达式中完成逻辑:
hana::types_c<S>用于获取序列S中所有元素的类型序列(包装为hana::type对象)- 通过
hana::fold或hana::all_of遍历类型序列,逐一检查每个类型是否满足callable_with_int概念 - 无需额外的辅助模板,代码更紧凑直观
内容的提问来源于stack exchange,提问作者HyperBoar
相关产品推荐
相关产品推荐

