Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does pack expansion fail in my std::tuple transformation type trait?

I'm trying to build the compile-time "tupled" version of std::transform. This type traits should take in a std::tuple, a unary type trait that "returns" a type (such as std::remove_pointer) and should produce a std::tuple whose types are the result of applying the type trait to the corresponding type of the input std::tuple

For example, my_tuple_trasform<std::tuple<int*, float&, double*>, std::remove_pointer>::type should be equivalent to std::tuple<int, float&, double>.

I could easily write a solution recursively, but I was trying to implement an "iterative" solution through an expansion pack, and I can't figure out what I'm getting wrong.

Here's my code:

template <typename Tuple, template<typename> typename TraitPredicate>
struct my_tuple_trasform;

template <template<typename> typename TraitPredicate, typename... Ts>
struct my_tuple_trasform<std::tuple<Ts...>, TraitPredicate>
{
    using type = std::tuple<(typename TraitPredicate<Ts>::type)...>;
};

The compiler produces an unhelpful error, where it points out that the expression

(typename TraitPredicate<Ts>::type)

is not recognized as a parameter pack and it also seems to think that the whole thing, ellipsis included, is just the first type of the std::tuple.

like image 843
Andrea Bocco Avatar asked Dec 03 '25 22:12

Andrea Bocco


1 Answers

It was close: you have to skip the parenthesis in using type = std::tuple<(typename TraitPredicate<Ts>::type)...>;

#include <tuple>

template <typename Tuple, template<typename> typename TraitPredicate>
struct my_tuple_trasform;

template <template<typename> typename TraitPredicate, typename... Ts>
struct my_tuple_trasform<std::tuple<Ts...>, TraitPredicate>
{
    using type = std::tuple<typename TraitPredicate<Ts>::type...>;
};

using T1 = std::tuple<int*, float&, double*>;
using T2 = my_tuple_trasform<T1, std::remove_pointer>::type;

static_assert (std::is_same_v<T2, std::tuple<int, float&, double>>);

int main() {}

Demo

like image 69
abcdefg Avatar answered Dec 05 '25 13:12

abcdefg



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!