mardi 7 avril 2020

C++ Parameter Pack type expansion

I was playing around with parameter packs in c++ and here's what I would like to achieve:

I have this 3 structs:

struct Base {
    Base(int x) : x(41) {}
    int x;
};

struct A : Base {
    A() : Base(41) {}
};

struct B : Base {
    B() : Base(42) {}
};

And I would like to create a generic function that returns a tuple with instances of the types specified, i.e.

magicFunction<A,B,A,B,A> == std::tuple{A(), B(), A(), B(), A()} 
magicFunction<A,B,A> == std::tuple{A(), B(), A()} 

I tried to use template specialization to expand the types but was unfortunately unable to do it (I understand why it doesn't compile, just don't know how to fix it :) )


template<typename isEmpty, typename ...T>
struct ExpanderImpl {

};

template<typename Head, typename ... Rest>
struct ExpanderImpl<std::false_type, Head, Rest...> {
    static std::tuple<Head, Rest...> getValues() {
        if(sizeof...(Rest) > 0) {
            return std::tuple_cat(std::tuple{Head()}, ExpanderImpl<std::false_type, Rest...>::getValues());
        } else {
            return std::tuple_cat(std::tuple{Head()}, ExpanderImpl<std::true_type, Rest...>::getValues());
        }
    }
};

template<typename ...Empty>
struct ExpanderImpl<std::true_type, Empty...> {
    static std::tuple<Empty...> getValues() {
        return {};
    }
};

template<typename ...T>
struct Expander {
    static std::tuple<T...> getValues() {
        if(sizeof...(T) > 0) {
            return ExpanderImpl<std::false_type, T...>::getValues();
        } else {
            return ExpanderImpl<std::true_type, T...>::getValues();
        }
    }

};

Any suggestions on how to fix it? Also, is there a better way of achieving what I want?

The full code can be found here here . Thanks for the help.

Aucun commentaire:

Enregistrer un commentaire