Search code examples
c++metaprogrammingvariadic-templatestemplate-meta-programming

how do we add up arrarys of the same length at compile time


experts! I am thinking how to use template programing to finish element-wise array addition at compile time using C++17 or C++20. For example, 3 arrs {1,2,3}, {,2,4,6}, {3,6,9} would be added up to { 6, 12, 18 }. All elements at the same index on the given arrays would be added up. The following is my initial thougt.

template <int... I>
struct Seq {};

template < template<int...> typename...Seqs >
struct addSeq{};

int main(){

    static_assert(std::is_same_v<addSeq<Seq<1, 2, 3>,Seq<2, 4, 6>, Seq<3, 6, 9> >::type, Seq<6, 12, 18>>);

}

Any expert could provide some insigh?

the first problem I am running into is if I use such template interface for struct addSeq{}:

template < template<int...> typename...Seqs >

then I would have pass every int..T for every Seqs to addSeq{}. I have no clue how to desgin struct addSeq such that I can only use it like

addSeq<Seq<1, 2, 3>,Seq<2, 4, 6>, Seq<3, 6, 9> >::type  

Solution

  • You can simply use template partial specialization to do this:

    #include <type_traits>
    
    template <int... I>
    struct Seq {};
    
    template <typename...Seqs >
    struct addSeq { };
    
    template <typename X, typename Y, typename... Rest>
    struct addSeq<X, Y, Rest...> : addSeq<typename addSeq<X, Y>::type, Rest...> { };
    
    template <int... Xs, int... Ys>
    struct addSeq<Seq<Xs...>, Seq<Ys...>> {
      using type = Seq<(Xs + Ys)...>;
    };
    
    static_assert(std::is_same_v<addSeq<Seq<1, 2, 3>,Seq<2, 4, 6>, Seq<3, 6, 9> >::type, Seq<6, 12, 18>>);