6. 表达式模板,向量运算
文献[12]展示了一个表达式模板(Expression Templates)的例子:
- #include <iostream> // std::cout
- #include <cmath> // std::sqrt()
-
- // 表达式类型
- class DExprLiteral { // 文字量
- double a_;
- public:
- DExprLiteral(double a) : a_(a) { }
- double operator()(double x) const { return a_; }
- };
- class DExprIdentity { // 自变量
- public:
- double operator()(double x) const { return x; }
- };
- template<class A, class B, class Op> // 双目操作
- class DBinExprOp {
- A a_; B b_;
- public:
- DBinExprOp(const A& a, const B& b) : a_(a), b_(b) { }
- double operator()(double x) const { return Op::apply(a_(x), b_(x)); }
- };
- template<class A, class Op> // 单目操作
- class DUnaryExprOp {
- A a_;
- public:
- DUnaryExprOp(const A& a) : a_(a) { }
- double operator()(double x) const { return Op::apply(a_(x)); }
- };
- // 表达式
- template<class A>
- class DExpr {
- A a_;
- public:
- DExpr() { }
- DExpr(const A& a) : a_(a) { }
- double operator()(double x) const { return a_(x); }
- };
-
- // 运算符,模板参数 A、B 为参与运算的表达式类型
- // operator /, division
- class DApDiv { public: static double apply(double a, double b) { return a / b; } };
- template<class A, class B> DExpr<DBinExprOp<DExpr<A>, DExpr<B>, DApDiv> >
- operator/(const DExpr<A>& a, const DExpr<B>& b) {
- typedef DBinExprOp<DExpr<A>, DExpr<B>, DApDiv> ExprT;
- return DExpr<ExprT>(ExprT(a, b));
- }
- // operator +, addition
- class DApAdd { public: static double apply(double a, double b) { return a + b; } };
- template<class A, class B> DExpr<DBinExprOp<DExpr<A>, DExpr<B>, DApAdd> >
- operator+(const DExpr<A>& a, const DExpr<B>& b) {
- typedef DBinExprOp<DExpr<A>, DExpr<B>, DApAdd> ExprT;
- return DExpr<ExprT>(ExprT(a, b));
- }
- // sqrt(), square rooting
- class DApSqrt { public: static double apply(double a) { return std::sqrt(a); } };
- template<class A> DExpr<DUnaryExprOp<DExpr<A>, DApSqrt> >
- sqrt(const DExpr<A>& a) {
- typedef DUnaryExprOp<DExpr<A>, DApSqrt> ExprT;
- return DExpr<ExprT>(ExprT(a));
- }
- // operator-, negative sign
- class DApNeg { public: static double apply(double a) { return -a; } };
- template<class A> DExpr<DUnaryExprOp<DExpr<A>, DApNeg> >
- operator-(const DExpr<A>& a) {
- typedef DUnaryExprOp<DExpr<A>, DApNeg> ExprT;
- return DExpr<ExprT>(ExprT(a));
- }
-
- // evaluate()
- template<class Expr>
- void evaluate(const DExpr<Expr>& expr, double start, double end, double step) {
- for(double i=start; i<end; i+=step) std::cout << expr(i) << ' ';
- }
-
- int main() {
- DExpr<DExprIdentity> x;
- evaluate( -x / sqrt( DExpr<DExprLiteral>(1.0) + x ) , 0.0, 10.0, 1.0);
- std::cin.get(); return 0;
- }
- -0 -0.707107 -1.1547 -1.5 -1.78885 -2.04124 -2.26779 -2.47487 -2.66667 -2.84605
|