加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

C矢量模板每组件操作

发布时间:2020-12-16 06:51:25 所属栏目:百科 来源:网络整理
导读:我正在重写我的项目的矢量数学部分,我想按照它们的类型和维数来概括矢量.载体 T,N表示类型为T的N维向量. templatetypename T,int Nstruct vector { T data[N];}; 我需要重写许多数学函数,其中大部分都是基于每个组件运行的.加法运算符的直接实现如下所示. te
我正在重写我的项目的矢量数学部分,我想按照它们的类型和维数来概括矢量.载体< T,N>表示类型为T的N维向量.

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

我需要重写许多数学函数,其中大部分都是基于每个组件运行的.加法运算符的直接实现如下所示.

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循环和临时变量?据我所知,编译器很可能会展开循环并对其进行优化.我只是不喜欢以这种方式实现所有性能关键数学函数的想法.它们都将被内联并在标题中,因此拥有许多这些函数也会产生一个丑陋的头文件.

我想知道是否有办法做到这一点,这将产生更优化的源代码.可能像variadic模板一样工作的方式.有点像这样的东西.

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

解决方法

一种方法是通过较低级别的“地图”功能:

这是一个完整的工作示例

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

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

首先声明你的工人“地图”功能 – 我这里有3张地图,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,typename FN>
static auto map(const vector<T,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,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),N> result;
   for(int i=0; i<N ;++i) {
      result.data[i] = f(vecA.data[i],vecB.data[i]);
   }
   return result;
}

现在使用帮助器通过lambdas定义更高级别的函数.我将定义二进制,二进制 –,一元 – 和e ^ x.哦和运算符<<所以我们可以看到发生了什么. 我很确定有一个更好的替代运算符和运算符中使用的lambdas,但我不记得它们

template<typename 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,N> operator-(const vector<T,T b) { return a-b;} );
}

template<typename 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,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,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;
}

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读