对不起,如果标题听起来令人困惑,但问题是。我正在研究一个极简主义的Expression Templates案例(参见下面的完整C ++ 98代码),我理解除了一个细节之外的所有内容:为什么Vector类型的赋值运算符需要有一个外来或第三方模板A为了工作?请参阅下面的注释行(抱歉,找不到行号的方法)
#include <iostream>
using namespace std;
template <class A>
struct Expr {
inline operator const A&() const {
return *static_cast<const A*>(this);
}
};
// ----------------------------------------------
// Addition Expression
// ----------------------------------------------
template<class A, class B>
class DExprSum : public Expr< DExprSum< A,B > > {
const A& a_;
const B& b_;
public:
DExprSum(const A& a, const B& b) : a_(a), b_(b) { }
double operator()(int i) const {
return (double)(a_[i] + b_[i]);
}
double operator[](int i) const {
return this->operator()(i);
}
};
template <class A, class B>
inline DExprSum<A, B> operator+(const Expr<A>& a, const Expr<B>& b) {
return DExprSum<A, B>(a, b);
};
// ----------------------------------------------
// A simple vector class
// ----------------------------------------------
template<class T>
class Vector : public Expr<Vector<T> > {
private:
T *p;
int len;
public:
Vector(int length) {
len = length;
p = new T[length];
};
T operator()(int i) const {
return p[i];
}
T& operator[](int i) const {
return p[i];
}
// <<<<<<------------ HERE why do I need a new template<class A>
// rather than simply using Expr<Vector<T> >
template<class A>
void operator=(const Expr<A>& expr) {
const A& a(expr);
// parallelize using OpenMP
#pragma omp parallel for schedule(runtime) // OMP_SCHEDULE=static,50 OMP_NUM_THREADS=10
for (int i=0; i < len; ++i) {
p[i] = a(i);
}
}
~Vector() {
delete[] p;
};
};
int main() {
Vector<double> a(3);
Vector<double> b(3);
Vector<double> c(3);
a[0] = 1;
a[1] = 2;
a[2] = 3;
b[0] = 2;
b[1] = 3;
b[2] = 4;
c = a + a + b + b;
for (int i = 0; i < 3; ++i) {
cout << c[i] << endl;
}
return 0;
}
如果我将赋值运算符定义更改为(实际上是它的目的):
void operator=(const Expr<Vector<T> >& expr) {
const Vector<T>& a(expr);
// parallelize using OpenMP
#pragma omp parallel for schedule(runtime) // OMP_SCHEDULE=static,50 OMP_NUM_THREADS=10
for (int i=0; i < len; ++i) {
p[i] = a(i);
}
}
我收到编译错误error: no viable overloaded '='
答案 0 :(得分:2)
因为传递给Vector<T>::operator=
的参数不是Expr<Vector<T>>
(特别是对于使用表达式模板的情况)。
对于c = a + a + b + b;
,您正在调用operator+()
三次,操作和参数将保存在表达式模板中。 a + a + b + b
的返回值为
DExprSum<DExprSum<DExprSum<Vector<double>, Vector<double>>, Vector<double>>, Vector<double>>
可以转换为
Expr<DExprSum<DExprSum<DExprSum<Vector<double>, Vector<double>>, Vector<double>>, Vector<double>>>
然后将模板参数A
解析为
DExprSum<DExprSum<DExprSum<Vector<double>, Vector<double>>, Vector<double>>, Vector<double>>`
但无法转换为Expr<Vector<double>>
。
修改强>
关于其他问题,
operator=
是一个模板函数。在调用模板函数时,无需指定模板参数,因为Template argument deduction。