繁体   English   中英

过滤增强hana中的元组

[英]Filtering a tuple in 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但contains似乎有效。

std::cout << contains<int,float,double>(5) << std::endl;   // 1
std::cout << contains<int,float,double>('c') << std::endl; // 0
std::cout << contains<int,float,double>(5.0f) << std::endl; // 1

为什么ht1的大小为0?

这里的问题实际上与Hana无关,它与推导出通用引用的方式有关。 只是为了清理东西, hana::type_c<T> == hana::type_c<U>正好等同于std::is_same<T, U>{} 在比较hana::type s时没有引用或cv-qualifier删除。 您可以查看这些规则的各种文章(例如thisthis )。

现在,让我通过您的代码并使用注释修改一些内容。 第一,

  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函数的对象 ,在某些情况下这可能是不实用的(如果你没有一个对象怎么办?)。 此外,将值与类型进行比较可能会令人困惑:

contains<int, char, double>(3.5) // wtf, 3.5 is not in [int, char, 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, char, double>(hana::type_c<double>)

但这是你的功能界面的一部分,我想你是一个比我更好的判断,知道你的界面需求是什么。

问题是T&& ,我认为它推断出类型为T&的类型T&这意味着hana::type_c<T> != hana::type_c<T&>修复是留下&&因为它们是不必要的。

template<class... Ts, class T>
constexpr auto contains(T){
  auto types = hana::tuple_t<Ts...>;
  return hana::find(types, hana::type_c<T>) != hana::nothing;
}

只需添加到您的回答,您ht1打电话containst的左值。 在传递右值和左值的情况下,下面演示了T&&

#include<boost/hana.hpp>

namespace hana = boost::hana;

template<class T>
void test1(T&&) {
  static_assert(hana::type_c<T> == hana::type_c<int>, "");
}

int main() {
  static_assert(hana::type_c<int> != hana::type_c<int&&>, "");
  test1(5);
  int x = 5;
  test1(x); //fails
}

铿锵输出:

main.cpp:7:3: error: static_assert failed ""
  static_assert(hana::type_c<T> == hana::type_c<int>, "");
  ^             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
main.cpp:14:3: note: in instantiation of function template specialization 'test1<int &>' requested here
  test1(x); //fails
  ^
1 error generated.

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM