了解 Boost.Hana 快速入门
Understanding Boost.Hana Quick start
我正在学习 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
是存储在 [=15= 的 first
条目中的类型],这是用hana::make_pair
得到的一对,但为什么这么复杂呢?我对所有这些 ::type
、decltype
、typename
和 hana::type_c
感到有点困惑。他们如何相互作用(在这种情况下,如果问题看起来很笼统)?
- 嗯,需要的
+
,我也很困惑。它有什么用?
既然我理所当然地认为T
就是我需要的类型,为什么我要用typeid(T) == t
来比较呢?
- 从
std::type_index
我读到 type_index
class 是 class 围绕 std::type_info
对象的包装器 ,
- 来自
std::type_info
我读到 class type_info
包含有关类型的特定于实现的信息,包括类型的名称和 表示比较两种类型是否相等或整理顺序,
- 和我从
typeid
读到(参考使用typeid(type)
)指的是一个std::type_info
表示类型type的对象,
似乎都相关,但我不明白 typeid(T)
与 class std::type_info
相比如何 std::type_index
从调用 a
上的 type
成员函数,我不知道它来自哪里。我希望有人能帮助我理解这一点。
在 return 语句中,当 typeid(T) == t
为真时,为什么需要 hana::second(case_)(*boost::unsafe_any_cast<T>(&a))
而 hana::second(case_)(a)
不起作用?
我将尝试回答有关 using
行的问题:
case_
是由 hana::make_pair(hana::type_c<T>, f)
创建的 hana::pair
类型的变量(第一个参数是类型的包装器)
hana::first(case_)
returns 对中的第一项(类型周围的 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
returns 对中第一项的实际类型(无论在 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 需要如此糟糕的转换语法。
我正在学习 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
是存储在 [=15= 的first
条目中的类型],这是用hana::make_pair
得到的一对,但为什么这么复杂呢?我对所有这些::type
、decltype
、typename
和hana::type_c
感到有点困惑。他们如何相互作用(在这种情况下,如果问题看起来很笼统)?- 嗯,需要的
+
,我也很困惑。它有什么用?
- 嗯,需要的
既然我理所当然地认为
T
就是我需要的类型,为什么我要用typeid(T) == t
来比较呢?- 从
std::type_index
我读到type_index
class 是 class 围绕std::type_info
对象的包装器 , - 来自
std::type_info
我读到 classtype_info
包含有关类型的特定于实现的信息,包括类型的名称和 表示比较两种类型是否相等或整理顺序, - 和我从
typeid
读到(参考使用typeid(type)
)指的是一个std::type_info
表示类型type的对象,
似乎都相关,但我不明白
typeid(T)
与 classstd::type_info
相比如何std::type_index
从调用a
上的type
成员函数,我不知道它来自哪里。我希望有人能帮助我理解这一点。- 从
在 return 语句中,当
typeid(T) == t
为真时,为什么需要hana::second(case_)(*boost::unsafe_any_cast<T>(&a))
而hana::second(case_)(a)
不起作用?
我将尝试回答有关 using
行的问题:
case_
是由hana::make_pair(hana::type_c<T>, f)
创建的hana::pair
类型的变量(第一个参数是类型的包装器)hana::first(case_)
returns 对中的第一项(类型周围的 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
returns 对中第一项的实际类型(无论在 hana::type_c 中构建的类型是什么)using T = typename decltype(+hana::first(case_))::type;
将该原始类型命名为T
(需要typename
位,因为 C++ 是一种复杂的语言,有时编译器需要提示一个事物是否是一种类型或不)
你需要一些机制来提取传递给 hana::make_pair 的原始类型——如果你正在构建一些东西来解决你的特定问题,你会使其更简单,但他们需要使库如此通用它将解决每个人的问题并增加复杂性。
至于第二 return
行:
该示例的整个前提是 switch_
被传递了一个 boost::any 并且它使用 boost::any.
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 需要如此糟糕的转换语法。