【问题标题】:Understanding Boost.Hana Quick start了解 Boost.Hana 快速入门
【发布时间】:2020-08-10 21:33:43
【问题描述】:

我正在通过Boost.Hana's User Manual 了解更多关于 C++ 模板元编程和函数式编程的信息。

关于Real world example,我还是漏掉了一些,都集中在下面函数的定义中:

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...);
};

以下是我的疑惑和问题:

  • 关于using 指令,我知道T 是存储在case_first 条目中的类型,这是用hana::make_pair 获得的一对,但为什么是这么复杂?我对所有::typedecltypetypenamehana::type_c 感到有些困惑。它们如何相互交互(在这种情况下,如果问题似乎很笼统)?

    • 嗯,需要的+ 也让我很困惑。它有什么用?
  • 一旦我理所当然地认为T 是我需要的那种类型,我为什么要拿typeid(T) == t 来比较它?

    • std::type_index 我读到type_index 类是std::type_info 对象的包装类
    • 来自std::type_info 我读到type_info 类包含有关类型的特定于实现的信息,包括类型的名称和意味着比较两种类型是否相等 或整理订购,
    • typeid我读到(参考使用typeid(type))指的是一个std::type_info对象,表示类型类型

    这一切似乎都是相关的,但我不知道typeid(T)(属于std::type_info)与std::type_index(来自调用a 上的type 成员函数)相比如何,我不知道它来自哪里。我希望有人能帮助我理解这一点。

  • typeid(T) == t 为真时的返回语句中,为什么需要hana::second(case_)(*boost::unsafe_any_cast&lt;T&gt;(&amp;a))hana::second(case_)(a) 不起作用?

【问题讨论】:

标签: c++ c++14 template-meta-programming boost-hana


【解决方案1】:

我将尝试回答有关using 行的问题:

  • case_ 是由hana::make_pair(hana::type_c&lt;T&gt;, f) 创建的hana::pair 类型的变量(第一个参数是一个类型的包装器)
  • hana::first(case_) 返回该对的第一项(类型的 hana::type_c 包装器)
  • +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_)) 计算为该对中第一项的类型(即 hana::type_c 包装器)
  • decltype(+hana::first(case_))::type 返回该对中第一项的实际类型(无论在 hana::type_c 中构造的类型是什么)
  • using T = typename decltype(+hana::first(case_))::type; 将该原始类型命名为 T(需要 typename 位,因为 C++ 是一种复杂的语言,有时编译器需要提示某个事物是否为类型)

您需要一些机器来提取传递给 hana::make_pair 的原始类型 - 如果您正在构建一些东西来仅解决您的特定问题,您会使其更简单,但他们需要使库如此通用以使其能够解决每个人的问题,这增加了复杂性。

至于第二个return 行:

该示例的全部前提是 switch_ 被传递了一个 boost::any 并使用 boost::any 的内容调用正确的 lambda。

hana::second(case_) 是最初提供给 switch_ 的 lambda 之一,因此如果您使用 hana::second(case_)(a),则 boost::any 会传递给您的 lambda,但 lambda 内的代码并不期望 boost::any所以错误消息说 std::to_string 不接受 boost::any。

您实际上可以使用hana::second(case_)(a),然后将 boost::any 参数转换回 lambda 中的原始类型。这实际上可以正常工作,但我认为 switch_ 应该为您做一些事情,以便 lambda 获得您期望的类型。

不幸的是 boost::any 需要如此糟糕的转换语法。

【讨论】:

  • 对于其他读者,here 是我将hana::second(case_)(*boost::unsafe_any_cast&lt;T&gt;(&amp;a)) 更改为hana::second(case_)(a) 时遇到的错误的要点。
猜你喜欢
  • 2014-11-12
  • 1970-01-01
  • 1970-01-01
  • 2019-03-09
  • 2012-03-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多