C ++ Vector Template Per-Component Operations

I am rewriting the vector mathematical part of my project, and I would like to generalize the vectors by their type and number of dimensions. A vector<T, N>is an N-dimensional vector of type T.

template<typename T, int N>
struct vector {
    T data[N];
};

I need to rewrite many mathematical functions, most of which will work based on each component. The following is a direct implementation of the addition operator.

template<typename T, int N>
vector<T, N> operator+(vector<T, N> lhs, vector<T, N> rhs) {
    vector<T, N> result;
    for (int i = 0; i < N; i++) {
        result[i] = lhs[i] + rhs[i];
    }
    return result;
}

: ( -?) for ? , , , . . , .

, , . , , , . - .

template<typename T, int N>
vector<T, N> operator+(vector<T, N> lhs, vector<T, N> rhs) {
    return vector<T, N>(lhs[0] + rhs[0], lhs[1] + rhs[1]...);
}
+4
3

- "map" :

#include <iostream>
#include <math.h>

template<typename T, int N>
struct vector {
    T data[N];
};

"map" - 3 map, map2, foreach.

template<typename T, int N, typename FN>
static void foreach(const vector<T,N> & vec, FN f) {
   for(int i=0; i<N ;++i) {
      f(vec.data[i]);
   }
}

template<typename T, int N, typename FN>
static auto map(const vector<T,N> & vec, FN f) -> vector<decltype(f(T(0))), N> {
   vector<decltype(f(T(0))), N> result;
   for(int i=0; i<N ;++i) {
      result.data[i] = f(vec.data[i]);
   }
   return result;
}

template<typename T1, typename T2, int N, typename FN>
static auto map2(const vector<T1,N> & vecA, 
                 const vector<T2,N> & vecB, 
                 FN f)
 -> vector<decltype(f(T1(0), T2(0))), N> {
   vector<decltype(f(T1(0), T2(0))), N> result;
   for(int i=0; i<N ;++i) {
      result.data[i] = f(vecA.data[i], vecB.data[i]);
   }
   return result;
}

, lambdas. +, , e^x. Oh operator<<, , .

, , operator+ operator-, .

template<typename T, int N>
vector<T,N> operator+(const vector<T,N> &lhs, const vector<T,N> &rhs) {
  return map2(lhs, rhs, [](T a,T b) { return a+b;} );
}

template<typename T, int N>
vector<T,N> operator-(const vector<T,N> &lhs, const vector<T,N> &rhs) {
  return map2(lhs, rhs, [](T a,T b) { return a-b;} );
}

template<typename T, int N>
vector<T,N> operator-(const vector<T,N> &vec) {
  return map(vec, [](T a) { return -a;} );
}

template<typename T, int N>
auto exp(const vector<T,N> &vec) -> vector<decltype(exp(T(0))), N> {
  return map(vec, [](T a) { return exp(a); } );
}

template<typename T, int N>
std::ostream & operator<<(std::ostream& os, const vector<T,N> &vec) {
  os<<"{";
  foreach(vec, [&os](T v) { os<<v<<", "; } );
  os<<"}";
  return os;
}

, ...

int main() {
  vector<int, 5> v1 = {1,2,3,4,5};
  vector<int, 5> v2 = {2,4,6,8,10};

  std::cout<<v1 << " + " << v2 << " = " << v1+v2<<std::endl;
  std::cout<<v1 << " - " << v2 << " = " << v1-v2<<std::endl;
  std::cout<<" exp( - " << v2 << " )= " << exp(-v1)<<std::endl;
}
0

, ( ). , , , .

, .. N = 3, 4, 5, , , , . . .

, :

template<typename T, int N>
vector<T, N> operator+(vector<T, N> lhs, vector<T, N> rhs) {
    vector<T, N> result;
    for (int i = 0; i < N; i++) {
        result[i] = lhs[i] + rhs[i];
    }
    return result;
}

, :

   template<typename T, int N>
    vector<T, N> operator+(vector<T, N> lhs, vector<T, N> rhs) {
        vector<T, N> result;
        result[0] = lhs[0] + rhs[0];
        result[1] = lhs[1] + rhs[1];
        ...
        result[N-1] = lhs[N-1] + rhs[N-1];
        return result;
    }

N 1, ...              + ( lhs, rhs) {            ;            [0] = lhs [0] + rhs [0];            ;       }

N 2, ...              + ( lhs, rhs) {            ;            [0] = lhs [0] + rhs [0];            [1] = lhs [1] + rhs [1];            ;       }

- N, , , , , , N = 5 N = 6 ?

, . , , :

template<typename T, int N, int IDX>
struct Plus
{
    void operator()(vector<T,N>& lhs, vector<T,N>& rhs, vector<T,N>& result)
    {
        Plus<T,N,IDX-1>()(lhs,rhs,result);
        result.data[IDX] = lhs.data[IDX] + rhs.data[IDX];
    }
};

, , , 0 :

template<typename T, int N>
struct Plus<T,N,-1>
{
    void operator()(vector<T,N>& lhs, vector<T,N>& rhs, vector<T,N>& result)
    {
        //noop
    }
};

, , +, Plus :

template<typename T, int N>
vector<T, N> operator+(vector<T, N> lhs, vector<T, N> rhs) {
    vector<T, N> result;
    Plus<T,N,N-1>()(lhs,rhs,result);
    return result;
}

, , . , , . , script, ++, , . , script, ++, SIMD- .

0
  • -, , , .
  • -, const , .

, std::index_sequence , - :

namespace detail
{

template<typename T, int N, std::size_t...Is>
vector<T, N> add(std::index_sequence<Is...>,
                 const vector<T, N>& lhs,
                 const vector<T, N>& rhs)
{
    return {{ (lhs[Is] + rhs[Is])... }};
}

}

template<typename T, int N>
vector<T, N> operator+(const vector<T, N>& lhs, const vector<T, N>& rhs) {
    return detail::add(std::make_index_sequence<N>{}, lhs, rhs);
}

0
source