简体   繁体   English

了解 Boost.Hana 快速入门

[英]Understanding Boost.Hana Quick start

I'm going through Boost.Hana's User Manual to learn more about template meta programming and functional programming in C++.我正在阅读Boost.Hana 的用户手册,以了解有关 C++ 中的模板元编程和函数式编程的更多信息。

As regards the Real world example , I still miss a few bits, all concentrated in the definition of the following function:至于现实世界的例子,我仍然错过了一些位,都集中在以下 function 的定义中:

template<typename Any, typename Default, typename Case, typename ...Rest>
auto process(Any a, std::type_index const& t, Default default_, Case& case_, Rest ...rest) {
    using T = typename decltype(+hana::first(case_))::type;
    return typeid(T) == t ? hana::second(case_)(*boost::unsafe_any_cast<T>(&a))
                          : process(a, t, default_, rest...);
};

Here are my doubts and questions:以下是我的疑问和问题:

  • Regarding the using directive, I do understand that T is meant to be the type which is stored in the first entry of case_ , which is a pair obtained with hana::make_pair , but why is that so convoluted?关于using指令,我知道T是存储在case_first条目中的类型,它是使用hana::make_pair获得的一对,但为什么这么复杂? I'm a bit confused by all those ::type , decltype , typename , and hana::type_c .我对所有这些::typedecltypetypenamehana::type_c有点困惑。 How do they interact with each other (in this case, if the question seems to general)?它们如何相互作用(在这种情况下,如果问题似乎很笼统)?

    • Well, that + which is needed, really puzzles me too.好吧,那个需要的+也让我很困惑。 What is it for?它是干什么用的?
  • Once I take for granted that T is that type I need, why do I compare it by typeid(T) == t ?一旦我理所当然地认为T是我需要的类型,为什么我要通过typeid(T) == t来比较它?

    • From std::type_index I read that The type_index class is a wrapper class around a std::type_info object ,std::type_index我读到type_index class 是围绕std::type_info object 的包装 class
    • from std::type_info I read that The class type_info holds implementation-specific information about a type, including the name of the type and means to compare two types for equality or collating order ,std::type_info我读到class type_info包含有关类型的特定于实现的信息,包括类型的名称以及比较两种类型是否相等或整理顺序的方法,
    • and from typeid I read (with reference to the use typeid(type) ) Refers to a std::type_info object representing the type type ,并从typeid我读到(参考使用typeid(type) )指的是代表类型 type 的std::type_info object

    which all seem relevant, but I don't get exactly how typeid(T) , which is of class std::type_info , is compared to std::type_index , which is comes from calling the type member function on a , which I don't know where it comes from.这一切似乎都是相关的,但我不知道typeid(T)是如何与std::type_index进行比较的,它是 class std::type_info ,它来自于在a上调用type成员 function ,我不知道不知道它来自哪里。 I hope someone can help me understand this point.我希望有人能帮助我理解这一点。

  • In the return statement for when typeid(T) == t is true, why is hana::second(case_)(*boost::unsafe_any_cast<T>(&a)) needed and hana::second(case_)(a) is not working?typeid(T) == t为真时的返回语句中,为什么需要hana::second(case_)(*boost::unsafe_any_cast<T>(&a))hana::second(case_)(a)不管用?

I'll try to answer the question about that using line:我将尝试using以下行来回答有关该问题的问题:

  • case_ is a variable of type hana::pair created by hana::make_pair(hana::type_c<T>, f) (the first parameter is a wrapper around a type) case_是由hana::make_pair(hana::type_c<T>, f)创建的 hana hana::pair类型的变量(第一个参数是类型的包装器)
  • hana::first(case_) returns the first item of the pair (the hana::type_c wrapper around the type) hana::first(case_)返回该对的第一项(围绕类型的 hana::type_c 包装器)
  • +hana::first(case_) uses the unary plus to convert the value from an lvalue to an rvalue (see https://www.boost.org/doc/libs/1_68_0/libs/hana/doc/html/structboost_1_1hana_1_1type.html ) +hana::first(case_)使用一元加号将值从左值转换为右值(参见https://www.boost.org/doc/libs/1_68_0/libs/hana/doc/html/structboost_1_1hana_1_1type。 html )
  • decltype(+hana::first(case_)) evaluates to the type of the first item of the pair (that hana::type_c wrapper) decltype(+hana::first(case_))计算为该对的第一项的类型(即 hana::type_c 包装器)
  • decltype(+hana::first(case_))::type returns the actual type of the first item of the pair (whatever the type was that was constructed inside hana::type_c) decltype(+hana::first(case_))::type返回该对中第一项的实际类型(无论在 hana::type_c 中构造的类型是什么)
  • using T = typename decltype(+hana::first(case_))::type; names that original type as T (the typename bit is needed because C++ is a complicated language and sometimes the compiler needs a hint about whether a thing is a type or not)将原始类型命名为T (需要typename位,因为 C++ 是一种复杂的语言,有时编译器需要提示某事物是否为类型)

You need some machinery to extract that original type that was passed to hana::make_pair - if you were building something to solve only your particular problem you would make it simpler, but they need to make the library so generic that it will solve everybody's problems and that adds complexity.您需要一些机器来提取传递给 hana::make_pair 的原始类型 - 如果您正在构建一些东西来仅解决您的特定问题,您会使其更简单,但他们需要使库如此通用以解决每个人的问题这增加了复杂性。

As for that second return line:至于第二条return线:

The whole premise of the example is that switch_ is passed a boost::any and it calls the right lambda with the contents of the boost::any.该示例的全部前提是switch_被传递了一个 boost::any 并使用 boost::any 的内容调用了正确的 lambda。

hana::second(case_) is one of the lambdas originally given to switch_ so if you use hana::second(case_)(a) then a boost::any gets passed to your lambda but the code inside the lambda isn't expecting a boost::any so the error message says std::to_string doesn't accept a boost::any. hana::second(case_)是最初提供给switch_的 lambdas 之一,因此如果您使用hana::second(case_)(a)则 boost::any 将传递给您的 lambda 但 lambda 中的代码不是期待 boost::any 所以错误消息说 std::to_string 不接受 boost::any。

You could actually use hana::second(case_)(a) and then cast the boost::any parameter back to the original type inside the lambda.您实际上可以使用hana::second(case_)(a) ,然后将 boost::any 参数转换回 lambda 中的原始类型。 That would actually work fine, but I think that is something switch_ should be doing for you so that the lambda gets the type you expect.这实际上可以正常工作,但我认为这是switch_应该为您做的事情,以便 lambda 获得您期望的类型。

It's just unfortunate that boost::any requires such a terrible cast syntax.不幸的是 boost::any 需要如此糟糕的转换语法。

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

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