带有表达式模板的多维数组模板 class
multidimensional array template class with expression templates
我试图通过实现我自己的多维数组来理解表达式模板 class。基本上,我分配一个连续的内存卡盘,然后用 () 运算符计算偏移量。
现在我想用表达式模板重载 +、/、*、-。维基百科中的示例非常具有说明性,但它假设数据块是双精度类型。我想将数据类型作为模板参数。我试图实现这一点,但我总是失败。这是到目前为止的代码:
namespace ader{
template<class E, typename T> class vexp{
inline unsigned size()const{return static_cast<E const&>(*this).size();};
inline T operator[](const unsigned &i) const{ return static_cast<E const&>(*this)[i];}
};
// ***************************************************************************** //
template<class E1, class E2, typename T>
class vsum:
public vexp<vsum<E1,E2,T>,T>{
const E1 &_u;
const E2 &_v;
public:
vsum(const E1 &u, const E2 &v): _u(u), _v(v){};
inline T operator[](const unsigned &i)const {return _u[i] + _v[i];};
inline unsigned size()const{return _u.size();};
};
// ***************************************************************************** //
template<typename T, unsigned nDer> class aDer: public ader::vexp<aDer<T,nDer>,T>{
protected:
unsigned n;
T d[nDer+1];
public:
unsigned size()const{return n;};
T operator[](const unsigned &i) {return d[i];};
T &operator[](const unsigned &i)const{return d[i];};
aDer():n(nDer), d{0}{};
aDer(const T &in): n(nDer), d{0}{d[0] = in;};
aDer(const T &in, const unsigned &idx): n(nDer), d{0}{d[0] = in; d[idx+1] = T(1);};
template<template<typename,unsigned> class U> aDer(const vexp<U<T,nDer>,T> &in){
for(unsigned ii=0; ii<=nDer; ++ii) d[ii] = in[ii];
}
};
template< class E1, class E2, typename T>
vsum<E1,E2,T> operator+(const E1 &u, const E2 &v){return vsum<E1,E2,T>(u,v);};
};
错误信息:
main2.cc: In function ‘int main()’:
main2.cc:15:27: error: no match for ‘operator+’ (operand types are ‘ader::aDer<float, 2>’ and ‘ader::aDer<float, 2>’)
ader::aDer<float,2> c= a+b;
代码中是否有明显错误?
EDIT1:main2.cc的内容:
#include "aut2.h"
#include <iostream>
using namespace std;
int main(){
ader::aDer<float,2> a(1.220334, 1);
ader::aDer<float,2> b(3.0, 0);
ader::aDer<float,2> c= a+b;
cerr<<c[0]<<endl;
}
您的 operator+
有一个不可推导的参数 T
。您需要删除此参数并从 E1
和 E2
.
推断 T
实现这一目标的一种方法是像这样定义 operator+
:
template <class E1, class E2>
auto operator+(const E1 &u, const E2 &v) -> vsum<E1, E2, decltype(u[0] + v[0])>
{
return { u,v };
}
另一种方法是通过使用 auto
和 decltype(auto)
来完全摆脱所有 类 中的 T
参数:
template <class E> class vexp {
...
inline decltype(auto) operator[](const unsigned &i) const { return static_cast<E const&>(*this)[i]; }
};
在上面的代码中,operator[]
将 return E::operator[]
是 return 的任何类型。
请注意,没有尾随 return 类型规范的 decltype(auto)
和 auto
是 C++14 功能。
我试图通过实现我自己的多维数组来理解表达式模板 class。基本上,我分配一个连续的内存卡盘,然后用 () 运算符计算偏移量。
现在我想用表达式模板重载 +、/、*、-。维基百科中的示例非常具有说明性,但它假设数据块是双精度类型。我想将数据类型作为模板参数。我试图实现这一点,但我总是失败。这是到目前为止的代码:
namespace ader{
template<class E, typename T> class vexp{
inline unsigned size()const{return static_cast<E const&>(*this).size();};
inline T operator[](const unsigned &i) const{ return static_cast<E const&>(*this)[i];}
};
// ***************************************************************************** //
template<class E1, class E2, typename T>
class vsum:
public vexp<vsum<E1,E2,T>,T>{
const E1 &_u;
const E2 &_v;
public:
vsum(const E1 &u, const E2 &v): _u(u), _v(v){};
inline T operator[](const unsigned &i)const {return _u[i] + _v[i];};
inline unsigned size()const{return _u.size();};
};
// ***************************************************************************** //
template<typename T, unsigned nDer> class aDer: public ader::vexp<aDer<T,nDer>,T>{
protected:
unsigned n;
T d[nDer+1];
public:
unsigned size()const{return n;};
T operator[](const unsigned &i) {return d[i];};
T &operator[](const unsigned &i)const{return d[i];};
aDer():n(nDer), d{0}{};
aDer(const T &in): n(nDer), d{0}{d[0] = in;};
aDer(const T &in, const unsigned &idx): n(nDer), d{0}{d[0] = in; d[idx+1] = T(1);};
template<template<typename,unsigned> class U> aDer(const vexp<U<T,nDer>,T> &in){
for(unsigned ii=0; ii<=nDer; ++ii) d[ii] = in[ii];
}
};
template< class E1, class E2, typename T>
vsum<E1,E2,T> operator+(const E1 &u, const E2 &v){return vsum<E1,E2,T>(u,v);};
};
错误信息:
main2.cc: In function ‘int main()’:
main2.cc:15:27: error: no match for ‘operator+’ (operand types are ‘ader::aDer<float, 2>’ and ‘ader::aDer<float, 2>’)
ader::aDer<float,2> c= a+b;
代码中是否有明显错误?
EDIT1:main2.cc的内容:
#include "aut2.h"
#include <iostream>
using namespace std;
int main(){
ader::aDer<float,2> a(1.220334, 1);
ader::aDer<float,2> b(3.0, 0);
ader::aDer<float,2> c= a+b;
cerr<<c[0]<<endl;
}
您的 operator+
有一个不可推导的参数 T
。您需要删除此参数并从 E1
和 E2
.
T
实现这一目标的一种方法是像这样定义 operator+
:
template <class E1, class E2>
auto operator+(const E1 &u, const E2 &v) -> vsum<E1, E2, decltype(u[0] + v[0])>
{
return { u,v };
}
另一种方法是通过使用 auto
和 decltype(auto)
来完全摆脱所有 类 中的 T
参数:
template <class E> class vexp {
...
inline decltype(auto) operator[](const unsigned &i) const { return static_cast<E const&>(*this)[i]; }
};
在上面的代码中,operator[]
将 return E::operator[]
是 return 的任何类型。
请注意,没有尾随 return 类型规范的 decltype(auto)
和 auto
是 C++14 功能。