为什么 boost::hana::tuple_c 的类型是实现定义的?

Why is the type of boost::hana::tuple_c implementation-defined?

tuple_cBoost.Hana documentation 状态:

Also note that the type of the objects returned by tuple_c and an equivalent call to make<tuple_tag> may differ.

后跟以下代码段:

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_cactual implementation 只是:

#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 包装器不是多余的吗?

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

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

不是权威,但我会说用 to_tuple 包裹 tuple_c 实际上是多余的。文档指出结果在功能上等同于 make_tuple 除了不保证类型相同。

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

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

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

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

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

实际上,FAQ 中的文档 has this covered

Why leave some container's representation implementation-defined?

First, it gives much more wiggle room for the implementation to perform compile-time and runtime optimizations by using clever representations for specific containers. For example, a tuple containing homogeneous objects of type T could be implemented as an array of type T instead, which is more efficient at compile-time. Secondly, and most importantly, it turns out that knowing the type of a heterogeneous container is not as useful as you would think. Indeed, in the context of heterogeneous programming, the type of the object returned by a computation is usually part of the computation too. In other words, there is no way to know the type of the object returned by an algorithm without actually performing the algorithm.