The Boost.Hana documentation for tuple_c
states:
Also note that the type of the objects returned by
tuple_c
and an equivalent call tomake<tuple_tag>
may differ.
followed by the following snippet:
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>)
);
However, the actual implementation for tuple_c
simply has:
#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
and, indeed, the code snippet works just fine without the to_tuple
wrapper:
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>)
);
Question: why is the actual type of tuple_c
implementation defined? Isn't the to_tuple
wrapper superfluous?
Actually, the documentation has this covered in a FAQ:
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.