Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

derive class from a tuple

I have an std::tuple given like this:

typedef std::tuple<t1, t2, t3> tuple_t;

Now, I want to transform t3_tuple into a similar tuple:

typedef std::tuple< T<t1>, T<t2>, T<t3> > derived_tuple_t;

In my case, for example, t1, t2, and t3 are primitives, and T is std::stack. In general, assume that that there might be t4 and so on.

Of course, my second definition already solves the problem, but I'd like the deriving to be automatic: Given only T and tuple_t, build me derived_tuple_t. Like this:

template <class T, class tuple_t> using derived_tuple_t = std::tuple</*???*/>;

Is something like this possible? Maybe a short solution?

like image 680
Johannes Avatar asked Nov 25 '25 01:11

Johannes


2 Answers

You could declare struct update_tuple with two template parameters:

  1. T - will be templated, and this parameter we will apply to the parameters in the tuple
  2. std::tuple with a variable number of template parameters.

Then just create an alias for a new tuple with arguments applied with T using pack expansion

#include <tuple>
#include <type_traits>
#include <vector>

template <template<class...> class, class>
struct update_tuple;

template <template <class...> class T, class... Args>
struct update_tuple<T, std::tuple<Args...>>
{
    using type = std::tuple<T<Args>...>;
};

int main()
{
    static_assert
    (
        std::is_same
        <
            std::tuple<std::vector<int>, std::vector<double>>,
            update_tuple<std::vector, std::tuple<int, double>>::type
        >::value,
        "They are not same"
    );
    return 0;
}

Thanks to @Xeo: Code will not fails if T could accept more than one template parameter(when others but first has defaults).

Example

like image 100
awesoon Avatar answered Nov 26 '25 17:11

awesoon


A little partial specialization using template template parameters should do the job (generalized to variadic templates, not only tuples):

template<template<class...> class TT, class ArgsT>
struct make_over;

template<template<class...> class TT, template<class...> class ArgsT, class... Ts>
struct make_over<TT, ArgsT<Ts...>>{ using type = ArgsT<TT<Ts>...>; };

template<template<class...> class TT, class ArgsT>
using MakeOver = typename make_over<TT, ArgsT>::type;

Note that this can be problematic with stdlibs that don't use true variadic templates, and emulate it instead with macro machinery and default template arguments (like MSVC).

Live example.

like image 31
Xeo Avatar answered Nov 26 '25 17:11

Xeo



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!