c – 在boost hana中过滤元组
template<class... Ts,class T> constexpr auto contains(T&&){ auto types = hana::to<hana::tuple_tag>(hana::tuple_t<Ts...>); return hana::bool_c<hana::find(types,hana::type_c<T>) != hana::nothing>; } auto ht = hana::make_tuple(1,2,3,'c'); auto ht1 = hana::filter(ht,[](auto t){ return contains<int,float,double>(t); }); //prints 0 std::cout << hana::size(ht1) << std::endl; 我不确定我是否正确使用增强hana但包含似乎有效. std::cout << contains<int,double>(5) << std::endl; // 1 std::cout << contains<int,double>('c') << std::endl; // 0 std::cout << contains<int,double>(5.0f) << std::endl; // 1 为什么ht1的大小为0? 解决方法
这里的问题实际上与Hana无关,它与推导出通用引用的方式有关.只是为了清理东西,hana :: type_c< T> == hana :: type_c< U>恰好等同于std :: is_same< T,U> {}.比较hana :: types时没有引用或cv-qualifier删除.您可以查看这些规则的各种文章(如
this或
this).
现在,让我通过您的代码并使用注释修改一些内容.第一, auto types = hana::to<hana::tuple_tag>(hana::tuple_t<Ts...>); 是多余的,因为你已经用hana :: tuple_t创建了一个hana :: tuple.因此,hana :: tuple_t< T ...>只够了.其次,有这条线: return hana::bool_c<hana::find(types,hana::type_c<T>) != hana::nothing>; 而不是检查hana :: find(…)!= hana :: nothing,我会使用hana :: contains,它更好地表达你的意图,也可能更优化.一般而言,尤其是与Hana的元编程库,不要试图推断什么会更快.尽可能清楚地表明你的意图,并希望我在实施方面正确地完成我的工作:-).因此,你最终会得到 return hana::bool_c<hana::contains(types,hana::type_c<T>)>; 现在,那个hana :: bool_c< ...>真的是多余的,因为hana :: contains已经返回一个boolean integral_constant.因此,上述等同于更简单 return hana::contains(types,hana::type_c<T>); 最后,把所有的位放在一起并简化,你得到 template<class... Ts,class T> constexpr auto contains(T&&){ return hana::contains(hana::tuple_t<Ts...>,hana::type_c<T>); } 我个人不喜欢参加T&&作为一个参数,当你想要的只是那个对象的类型.实际上,这会迫使你实际提供一个包含函数的对象,在某些情况下这可能是不实用的(如果你没有一个对象怎么办?).此外,将值与类型进行比较可能会令人困惑: contains<int,char,double>(3.5) // wtf,3.5 is not in [int,double]! 相反,如果它是我自己的代码,我会写下面的内容: template<class... Ts,class T> constexpr auto contains(T type){ return hana::contains(hana::tuple_t<Ts...>,type); } // and then use it like contains<int,double>(hana::type_c<double>) 但这是你的功能界面的一部分,我想你是一个比我更好的判断,知道你的界面需求是什么. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |