Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
332 views
in Technique[技术] by (71.8m points)

c++ - How to create a type list (for variadic templates) that contains n-times the same type?

I would like my class

template <class T, unsigned int n>
class X;

to create a std::tuple that contains n times the type T. Is there a particularly neat way for this? Is there also a nice way to do this for arbitrary variadic template classes?

This is what I did first:

#include <tuple>

template <class, unsigned int, class>
struct simple_repeat_helper;

template <class T, unsigned int n, class... Args>
struct simple_repeat_helper<T, n, std::tuple<Args...>>
{
    typedef typename simple_repeat_helper<T, n-1, std::tuple<Args..., T>>::type type;
};

template <class T, class... Args>
struct simple_repeat_helper<T, 0, std::tuple<Args...>>
{
    typedef std::tuple<Args...> type;
};

template <class T, unsigned int n>
struct simple_repeat
{
    using type = typename simple_repeat_helper<T, n, std::tuple<>>::type;
};

But actually, I do not need this for std::tuple, but for another class that acts similarly. So I thought that I would create a version that is a little bit more generic:

template <class, unsigned int, template <class...> class, class>
struct repeat_helper;

template <class T, template <class...> class M, class... Args>
struct repeat_helper<T, 0, M, M<Args...>>
{
    typedef M<Args...> type;
};

template <class T, unsigned int n, template <class...> class M, class... Args>
struct repeat_helper<T, n, M, M<Args...>>
{
    typedef typename repeat_helper<T, n-1, M, M<Args..., T>>::type type;
};

template <class T, unsigned int n, template <class...> class M = std::tuple>
struct repeat
{
    using type = typename repeat_helper<T, n, M, M<>>::type;
};

I thought that I could use it like this:

repeat<double, 5, std::tuple>::type x = std::make_tuple( 1., 2., 3., 4., 5. ); 

But unfortunately it fails to compile due to:

ambiguous class template instantiation for ‘struct repeat_helper<double, 0u, std::tuple, std::tuple<double, double, double, double, double> >’

Any help on this error would be appreciated!

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

I would do it this way:

template<typename, typename>
struct append_to_type_seq { };

template<typename T, typename... Ts, template<typename...> class TT>
struct append_to_type_seq<T, TT<Ts...>>
{
    using type = TT<Ts..., T>;
};

template<typename T, unsigned int N, template<typename...> class TT>
struct repeat
{
    using type = typename
        append_to_type_seq<
            T,
            typename repeat<T, N-1, TT>::type
            >::type;
};

template<typename T, template<typename...> class TT>
struct repeat<T, 0, TT>
{
    using type = TT<>;
};

As a small test:

#include <type_traits>
#include <tuple>

template<typename... Ts>
struct X { };

int main()
{
    repeat<double, 5, std::tuple>::type t = std::make_tuple(1., 2., 3., 4., 5.);
    static_assert(
        std::is_same<
            decltype(t),
            std::tuple<double, double, double, double, double>
        >::value, "!");

    repeat<double, 3, X>::type y;
    static_assert(
        std::is_same<decltype(y), X<double, double, double>>::value, "!");
}

Finally, a live example.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...