2

状态的Boost.Hana 文档tuple_c

另请注意,返回的对象类型tuple_c和等效调用make<tuple_tag>可能不同。

后跟以下代码段:

BOOST_HANA_CONSTANT_CHECK(
    hana::to_tuple(hana::tuple_c<int, 0, 1, 2>)
        ==
    hana::make_tuple(hana::int_c<0>, hana::int_c<1>, hana::int_c<2>)
);

然而,实际的实现只是tuple_c

#ifdef BOOST_HANA_DOXYGEN_INVOKED
    template <typename T, T ...v>
    constexpr implementation_defined tuple_c{};
#else
    template <typename T, T ...v>
    constexpr hana::tuple<hana::integral_constant<T, v>...> tuple_c{};
#endif

to_tuple而且,事实上,代码片段在没有包装器的情况下工作得很好:

BOOST_HANA_CONSTANT_CHECK(
    hana::tuple_c<int, 0, 1, 2>
        ==
    hana::make_tuple(hana::int_c<0>, hana::int_c<1>, hana::int_c<2>)
);

问题:为什么要tuple_c定义实际的实现类型?包装不是to_tuple多余的吗?

4

3 回答 3

3

实际上,文档在常见问题解答中对此进行了介绍:

为什么要定义一些容器的表示实现?

首先,它为实现提供了更多的回旋余地,通过对特定容器使用巧妙的表示来执行编译时和运行时优化。例如,可以将包含 T 类型的同类对象的元组实现为 T 类型的数组,这在编译时更有效。其次,也是最重要的,事实证明,了解异构容器的类型并没有您想象的那么有用。实际上,在异构编程的上下文中,计算返回的对象类型通常也是计算的一部分。换句话说,如果不实际执行算法,就无法知道算法返回的对象的类型。

于 2018-04-30T21:30:00.123 回答
3

短语“实现定义”不描述实现。它明确指出,出于某种原因,故意未记录实现选择。当然它是以某种方式实现的。用户不应依赖任何特定的实现,而应仅使用文档化的 API。

不记录实现选择是一个明智的默认设置,除非有特定的理由记录它。即使今天只有一个明显的选择也是如此,因为明天事情可能会改变。

于 2018-04-30T14:07:21.627 回答
2

不以权威说话,但我会说包装实际上是多余的tuple_cto_tuple该文档指出,结果在功能上等同于,make_tuple但不保证类型相同。

一种可能的优化是返回如下内容:

template <auto ...i>
struct tuple_c_t { };

为了确保我提出了一个拉取请求,看看我们是否可以从示例中删除多余的转换。

https://github.com/boostorg/hana/pull/394

更新:Boost.Hana 的作者确认转换是不必要的,示例已更新以反映这一点。

于 2018-04-30T16:11:09.883 回答