0

Brain hurt yet?

I'm working on a tuple type transformation helper, and have a problem. Either I duplicate code, or I wrap a template template. I'm having trouble getting this to work though.

Here's what I need to work with:

template<template<typename> class trans> struct no_index_transformer
{
    template<size_t, typename transform_t> struct transformer
    {
        using t = typename trans<transform_t>::t;
    };
};

no_index_transformer takes a template template of a transformer that doesn't have a size_t (index) passed to it. The internal transformer template is what I need to pass. I get an error when I do that though, and so I'm not sure what the right way to pass no_index_transformer<>::transformer is.

I get an error on the following line:

template<template<typename> class transformer, typename tuple> using transform_tuple_t                  
    = transform_tuple_index<no_index_transformer<transformer>::transformer, 0, tuple>::t;

"Template argument for template template parameter must be a class template or type alias template."

Here's the transformer:

template<typename, typename> struct tuple_cat;
template<typename... types_one, typename... types_two> struct tuple_cat<std::tuple<types_one...>, std::tuple<types_two...>>
{
public:
    using t = std::tuple<types_one..., types_two...>;
};

template<template<size_t, typename> class transformer, size_t index, typename tuple> class transform_tuple_index;
template<template<size_t, typename> class transformer, size_t index, typename current_t, typename... types> class transform_tuple_index<transformer, index, std::tuple<current_t, types...>>
{
    using current = std::tuple<typename transformer<index, current_t>::t>;
    using next = typename transform_tuple_index<transformer, index + 1, std::tuple<types...>>::t;
    using combined = typename tuple_cat<current, next>::t;
    static constexpr bool test_{ std::is_same<std::tuple<void>, next>::value };

public:
    using t = typename std::conditional<test_, current, combined>::type;
};
template<template<size_t, typename> class transformer, size_t index> class transform_tuple_index<transformer, index, std::tuple<>>
{
public:
    using t = std::tuple<void>;
};

I'd rather not have to write and maintain multiple versions of the transformer, which is why I'd like to use a wrapper to convert an incoming template to one that takes an unused size_t.

Is there a way for me to properly pass this template?

For reference, adding template<> and/or typename before the name I want to pass doesn't work.

T.C.
  • 133,968
  • 17
  • 288
  • 421
Michael Gazonda
  • 2,720
  • 1
  • 17
  • 33

1 Answers1

6

The correct syntax is

template<template<typename> class transformer, typename tuple> 
using transform_tuple_t                  
    = typename transform_tuple_index<no_index_transformer<transformer>::template transformer, 0, tuple>::t;
//    ^^^^^^^^                                                          ^^^^^^^^

Since no_index_transformer<transformer> is dependent, you need to tell the compiler that no_index_transformer<transformer>::transformer is a template with template (not template<>). Since transform_tuple_index<...> is dependent, you need to tell the compiler that transform_tuple_index<...>::t is a type using typename.

T.C.
  • 133,968
  • 17
  • 288
  • 421