【发布时间】:2017-12-16 14:08:48
【问题描述】:
有一个泛型类 Vector 扩展了 std::array,还有一个泛型类 Expression 定义了向量的可能表达式。
例如:
向量 A({1,2,3});
向量 B({2,2,2});
和表达式:
A + B;
A * B;
A - B;
A / B;
现在我需要这个表达式 A ** B,它返回一个 double 作为两个向量 A 和 B 的标量产生,结果必须是:2+4+6=12。问题是operator**的实现!!!
我该如何写这个操作符**?
我的想法是重载 Vector 的解引用 operator* 返回一个指针,然后重载 struct-Mul oder multiply operator* ...无法解决此错误:
“不存在从“Expression, Mul, Vector *>”到“double”的合适转换函数”
template<typename Left, typename Op, typename Right> class Expression {
const Left& m_left;
const Right& m_right;
public:
typedef typename Left::value_type value_type;
// Standard constructor
Expression(const Left& l, const Right& r) : m_left{ l }, m_right{ r } {}
size_t size() const {
return m_left.size();
}
value_type operator[](int i) const {
return Op::apply(m_left[i], m_right[i]);
}
};
struct Mul {
template<typename T> static T apply(T l, T r) {
return l * r;
}
};
template<typename Left, typename Right>
Expression<Left, Mul, Right> operator*(const Left& l, const Right& r) {
return Expression<Left, Mul, Right>(l, r);
}
.......................
// Class Vector extends std::array
template<class T, size_t S> class Vector : public array<T, S> {
public:
// Standard constructor
Vector<T, S>(array<T, S>&& a) : array<T, S>(a) {}
// Initializerlist constructor
Vector(const initializer_list<T>& data) {
size_t s = __min(data.size(), S);
auto it = data.begin();
for (size_t i = 0; i < s; i++)
this->at(i) = *it++;
}
};
.....................................
int main {
Vector<double, 5> A({ 2, 3, 4, 5, 6 });
Vector<double, 5> B({ 3, 3, 3, 3, 3 });
Vector<double, 5> C;
C = A * B; // is a Vector: [6, 9, 12, 15, 18] and it works.
double d = A**B; // but this one does not work, the error message is: "no suitable conversion function from "Expression<Vector<double, 5U>, Mul, Vector<double, 5U> *>" to "double" exists"
cout << d << endl; // must give me: 60
}
【问题讨论】:
-
这几乎是不可能的,你最好重载另一个运算符,如右移或!
-
C++ 中没有
operator**。 -
您不能使用
**表示法,因为C++ 没有**运算符,也不支持定义全新的运算符。如果需要,您可以重载普通的单曲*。或者您可以定义一个伪运算符,如%dot%,这是一种滥用符号,其中第一个%为您的向量和dot的类型调用%的重载,产生一些结果,然后将其传递给%再次重载,第二个向量。但是为什么不考虑一个简单的命名函数呢?简单且可维护。 -
KIA 另一种方法是在私有类型上使用解引用运算符和乘法运算符
标签: c++ templates vector overloading