11.07.2015 Views

Understanding C++ Expression Templates - Angelika Langer

Understanding C++ Expression Templates - Angelika Langer

Understanding C++ Expression Templates - Angelika Langer

SHOW MORE
SHOW LESS
  • No tags were found...

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

1<strong>Understanding</strong> <strong>C++</strong><strong>Expression</strong> <strong>Templates</strong><strong>Angelika</strong> <strong>Langer</strong>Training / Consultinghttp://www.<strong>Angelika</strong><strong>Langer</strong>.comObjectivesWhat are expression templates?! an example of using templates for runtime-efficientcomputations! an example of modern template programming techniques– template meta-programming– generative programming© Copyright 1995-2000 by <strong>Angelika</strong> <strong>Langer</strong>. All Rights Reserved.http://www.<strong>Angelika</strong><strong>Langer</strong>.com(2)last update: 11/7/2005 ,21:37


2Where it all started ...! Erwin Unruh's prime number program ...– does not compile, but– calculates the prime numbers at compile-time and– emits them in error messages.! works via recursive template evaluation! useful for– evaluation of expressions (vector dot product, matrix operations)– calculation of constants (square root of N, prime numbers)– evaluation of logical expression (more readable STL functors)© Copyright 1995-2000 by <strong>Angelika</strong> <strong>Langer</strong>. All Rights Reserved.http://www.<strong>Angelika</strong><strong>Langer</strong>.com(3)last update: 11/7/2005 ,21:37! compile-time computation of constant values– factorial– square root! compile-time evaluation of expressions– dot product– arithmetic expression! more examples of modern template programming– compile-time polymorphism– policy classes– template meta-programmingAgenda© Copyright 1995-2000 by <strong>Angelika</strong> <strong>Langer</strong>. All Rights Reserved.http://www.<strong>Angelika</strong><strong>Langer</strong>.com(4)last update: 11/7/2005 ,21:37


3Runtime Computation of FactorialThe factorial of n is 1·2 ·... ·(n-1) ·n, andthe factorial of 0 is 1.A recursive factorial function:int factorial (int n){ return (n==0) ? 1: n*factorial(n-1); }cout


4Agenda! compile-time computation of constant values– factorial– square root! compile-time evaluation of expressions– dot product– arithmetic expression! more examples of modern template programming– compile-time polymorphism– policy classes– template meta-programming© Copyright 1995-2000 by <strong>Angelika</strong> <strong>Langer</strong>. All Rights Reserved.http://www.<strong>Angelika</strong><strong>Langer</strong>.com(7)last update: 11/7/2005 ,21:37Compile-Time Computation of Square RootGiven N, compute a compile-time table size ceil(sqrtsqrt(N))(N)).Example:int table[Root::root];Beginning of recursion:template struct Root;Root => Root© Copyright 1995-2000 by <strong>Angelika</strong> <strong>Langer</strong>. All Rights Reserved.http://www.<strong>Angelika</strong><strong>Langer</strong>.com(8)last update: 11/7/2005 ,21:37


5The RecursionRecursive definition of Root::root:template struct Root {static const size_t root =Root::root;static const size_t mean = (Low+High)/2;static const bool down = ((mean*mean)>=Size);};Root => Rootmean = (1+10)/2 = 5down = (5*5>=10) = true© Copyright 1995-2000 by <strong>Angelika</strong> <strong>Langer</strong>. All Rights Reserved.http://www.<strong>Angelika</strong><strong>Langer</strong>.com(9)last update: 11/7/2005 ,21:37End of the RecursionRoot => Rootmean = (1+5)/2 = 3down = (3*3>=10) = falseRoot => Rootmean = (4+5)/2 = 4down = (4*4>=10) = trueEnd of recursion:template struct Root{ static const size_t root = Mid; };© Copyright 1995-2000 by <strong>Angelika</strong> <strong>Langer</strong>. All Rights Reserved.http://www.<strong>Angelika</strong><strong>Langer</strong>.com(10)last update: 11/7/2005 ,21:37


6ResultGiven N, compute a compile-time table size ceil(sqrtsqrt(N))(N))!Example:int table[Root::root];1 4 5 10RootRootRootRoot© Copyright 1995-2000 by <strong>Angelika</strong> <strong>Langer</strong>. All Rights Reserved.http://www.<strong>Angelika</strong><strong>Langer</strong>.com(11)last update: 11/7/2005 ,21:37! compile-time computation of constant values– factorial– square root! compile-time evaluation of expressions– dot product– arithmetic expression! more examples of modern template programming– compile-time polymorphism– policy classes– template meta-programmingAgenda© Copyright 1995-2000 by <strong>Angelika</strong> <strong>Langer</strong>. All Rights Reserved.http://www.<strong>Angelika</strong><strong>Langer</strong>.com(12)last update: 11/7/2005 ,21:37


7Goal! efficient computation of arithmetic expressions! example:– dot product of 2 vectors of dimension Nint a[4] = {1,100,0,-1};int b[4] = {2,2,2,2};dot(a,b);! more generally:– arithmetic operations on multi-dimensional matrices© Copyright 1995-2000 by <strong>Angelika</strong> <strong>Langer</strong>. All Rights Reserved.http://www.<strong>Angelika</strong><strong>Langer</strong>.com(13)last update: 11/7/2005 ,21:37More Dynamic Use! compile-time computation of integrals5.0x1 + x1.0template double integrate (ExprT e,double from,double to,size_t n){ double sum=0, step=(to-from)/n;for (double i=from+step/2; i


8Gauss Distributiondouble sigma=2.0, mean=5.0;const double Pi = 3.141593;cout


9Agenda! compile-time computation of constant values– factorial– square root! compile-time evaluation of expressions– dot product– arithmetic expression! more examples of modern template programming– compile-time polymorphism– policy classes– template meta-programming© Copyright 1995-2000 by <strong>Angelika</strong> <strong>Langer</strong>. All Rights Reserved.http://www.<strong>Angelika</strong><strong>Langer</strong>.com(17)last update: 11/7/2005 ,21:37<strong>Understanding</strong> <strong>Expression</strong> <strong>Templates</strong>! try to understand template approach as a alternative to theclassic OO approach! expressions evaluation is an example of patterns in GOF– composite– interpreter© Copyright 1995-2000 by <strong>Angelika</strong> <strong>Langer</strong>. All Rights Reserved.http://www.<strong>Angelika</strong><strong>Langer</strong>.com(18)last update: 11/7/2005 ,21:37


10The Composite PatternThe Composite pattern provides a way to represent a partwholerelationship where the client can ignore thedifference between individual objects and compositions ofobjects.! The leaf (terminal) defines the behavior for primitiveobjects in the composition.! The composite (non-terminal) defines the behavior forcomponents consisting of leaves.Examples:– syntax trees, expression evaluation– aggregations and recursive structures and algorithms© Copyright 1995-2000 by <strong>Angelika</strong> <strong>Langer</strong>. All Rights Reserved.http://www.<strong>Angelika</strong><strong>Langer</strong>.com(19)last update: 11/7/2005 ,21:37The Composite PatternComponentOperation()LeafOperation()Compositelist gOperation()for all children:g->Operation()© Copyright 1995-2000 by <strong>Angelika</strong> <strong>Langer</strong>. All Rights Reserved.http://www.<strong>Angelika</strong><strong>Langer</strong>.com(20)last update: 11/7/2005 ,21:37


11A Typical Composite StructureaCompositeaLeaf aLeaf aCompositeaLeafaLeaf aLeaf aLeaf© Copyright 1995-2000 by <strong>Angelika</strong> <strong>Langer</strong>. All Rights Reserved.http://www.<strong>Angelika</strong><strong>Langer</strong>.com(21)last update: 11/7/2005 ,21:37An Example - Vector Dot ProductComponent:– dot product of vectors of dimension NLeaf:– simple product of two numerical values, i.e. the dotproduct of a vector of dimension 1Composite:– consists of a leaf (dimension 1) and a composite(dimension N-1)– calculation of the sum of the leaf’s value and thecomposite’s value© Copyright 1995-2000 by <strong>Angelika</strong> <strong>Langer</strong>. All Rights Reserved.http://www.<strong>Angelika</strong><strong>Langer</strong>.com(22)last update: 11/7/2005 ,21:37


12OO Implementation à la GOFDotProductevaluate()SimpleProductfloat a,bevaluate()CompositeProductSimpleProduct* sCompositeProduct* cevaluate()a * bs->evaluate() + c->evaluate()© Copyright 1995-2000 by <strong>Angelika</strong> <strong>Langer</strong>. All Rights Reserved.http://www.<strong>Angelika</strong><strong>Langer</strong>.com(23)last update: 11/7/2005 ,21:37Composite Structure of Dot ProductaDotProductdimension: NaSimpleProductaCompositeProductdimension: N-1aSimpleProductaCompositeProductdimension: N-2aSimpleProductaCompositeProductdimension: N-3© Copyright 1995-2000 by <strong>Angelika</strong> <strong>Langer</strong>. All Rights Reserved.http://www.<strong>Angelika</strong><strong>Langer</strong>.com(24)last update: 11/7/2005 ,21:37


13The ComponentThe base class that defines the interface common to leaves andcomposites:template class DotProduct {public:virtual ~DotProduct () {}virtual T eval() = 0;};© Copyright 1995-2000 by <strong>Angelika</strong> <strong>Langer</strong>. All Rights Reserved.http://www.<strong>Angelika</strong><strong>Langer</strong>.com(25)last update: 11/7/2005 ,21:37The Compositetemplate class CompositeDotProduct : public DotProduct {public:CompositeDotProduct (T* a, T* b, size_t dim):s(new SimpleDotProduct(a,b)),c((dim==1)?0:new CompositeDotProduct(a+1,b+1,dim-1)){}virtual ~CompositeDotProduct () { delete c; delete s; }virtual T eval(){ return (s->eval() + ((c)?c->eval():0)); }protected:SimpleDotProduct* s;CompositeDotProduct * c;};© Copyright 1995-2000 by <strong>Angelika</strong> <strong>Langer</strong>. All Rights Reserved.http://www.<strong>Angelika</strong><strong>Langer</strong>.com(26)last update: 11/7/2005 ,21:37


14The Leaftemplate class SimpleDotProduct : public DotProduct {public:SimpleDotProduct (T* a, T* b) :v1(a), v2(b) {}virtual T eval() { return (*v1)*(*v2); }private:T* v1; T* v2;};© Copyright 1995-2000 by <strong>Angelika</strong> <strong>Langer</strong>. All Rights Reserved.http://www.<strong>Angelika</strong><strong>Langer</strong>.com(27)last update: 11/7/2005 ,21:37The code that initiates the recursive evaluation of thecomposite structure:The Clienttemplate T dot(T* a, T* b, size_t dim){ return (dim==1)? SimpleDotProduct(a,b).eval(): CompositeDotProduct(a,b,dim).eval();}int a[4] = {1,100,0,-1};int b[4] = {2,2,2,2};dot(a,b,4);© Copyright 1995-2000 by <strong>Angelika</strong> <strong>Langer</strong>. All Rights Reserved.http://www.<strong>Angelika</strong><strong>Langer</strong>.com(28)last update: 11/7/2005 ,21:37


15A Simplified OO ImplementationEliminate the representation of the composite and the leafobject as data members.! Instead of passing information to the constructor andmemorizing them for subsequent evaluation,! pass them to the directly to the evaluation function.SimpleDotProduct (T* a, T* b) :v1(a), v2(b) {}virtual T eval() { return (*v1)*(*v2); }becomesT eval(T* a, T* b, size_t dim) { return (*a)*(*b); }© Copyright 1995-2000 by <strong>Angelika</strong> <strong>Langer</strong>. All Rights Reserved.http://www.<strong>Angelika</strong><strong>Langer</strong>.com(29)last update: 11/7/2005 ,21:37A Simplified OO Implementationtemplate class CompositeDotProduct : public DotProduct {public:virtual T eval(T* a, T* b, size_t dim){ return SimpleDotProduct().eval(a,b,dim)+ ((dim==1) ? 0: CompositeDotProduct().eval(a+1,b+1,dim-1));}};template class SimpleDotProduct : public DotProduct {public:virtual T eval(T* a, T* b, size_t dim){ return (*a)*(*b); }};© Copyright 1995-2000 by <strong>Angelika</strong> <strong>Langer</strong>. All Rights Reserved.http://www.<strong>Angelika</strong><strong>Langer</strong>.com(30)last update: 11/7/2005 ,21:37


16A Simplified OO ImplementationDotProductevaluate()SimpleProductevaluate()CompositeProductevaluate()a * bSimpleProduct().evaluate()+ CompositeProduct().evaluate()© Copyright 1995-2000 by <strong>Angelika</strong> <strong>Langer</strong>. All Rights Reserved.http://www.<strong>Angelika</strong><strong>Langer</strong>.com(31)last update: 11/7/2005 ,21:37Implementation Using <strong>Templates</strong>! The template solution does not need a base class.– Eliminate the Component base class.! Implement the Composite as a class template usingstructural information as template arguments.– The dimension of the vector becomes a non-type templateargument of the Composite.! Implement the Leaf as a specialization of the Composite.– The SimpleDotProduct is a specialization of theCompositeDotProduct for dimension N = 1.! Instead of run time recursion use compile time recursion.– Replace the recursive invocation of the virtual evaluation functionby recursive template instantiation of a static evaluation function.© Copyright 1995-2000 by <strong>Angelika</strong> <strong>Langer</strong>. All Rights Reserved.http://www.<strong>Angelika</strong><strong>Langer</strong>.com(32)last update: 11/7/2005 ,21:37


17Implementation Using <strong>Templates</strong>DotProductstaticevaluate()DimensionDotProduct::evaluate() + DotProduct::evaluate()DotProductstaticevaluate()1a * b© Copyright 1995-2000 by <strong>Angelika</strong> <strong>Langer</strong>. All Rights Reserved.http://www.<strong>Angelika</strong><strong>Langer</strong>.com(33)last update: 11/7/2005 ,21:37The Compositetemplate class DotProduct {public:static T eval(T* a, T* b){ return DotProduct::eval(a,b)+ DotProduct::eval(a+1,b+1);}};© Copyright 1995-2000 by <strong>Angelika</strong> <strong>Langer</strong>. All Rights Reserved.http://www.<strong>Angelika</strong><strong>Langer</strong>.com(34)last update: 11/7/2005 ,21:37


19Composite and InterpreterThe dot product example is a degenerated form of aComposite because! every Composite consists of exactly one Leaf and and oneComposite, and! there is only one type of Leaf and one type of Composite.The Interpreter pattern is a related pattern.! The syntax tree in the Interpreter pattern is a Composite.Let us discuss alternative implementations of the Interpreterpattern.© Copyright 1995-2000 by <strong>Angelika</strong> <strong>Langer</strong>. All Rights Reserved.http://www.<strong>Angelika</strong><strong>Langer</strong>.com(37)last update: 11/7/2005 ,21:37! compile-time computation of constant values– factorial– square root! compile-time evaluation of expressions– dot product– arithmetic expression! more examples of modern template programming– compile-time polymorphism– policy classes– template meta-programmingAgenda© Copyright 1995-2000 by <strong>Angelika</strong> <strong>Langer</strong>. All Rights Reserved.http://www.<strong>Angelika</strong><strong>Langer</strong>.com(38)last update: 11/7/2005 ,21:37


20The Interpreter PatternThe Interpreter pattern provides a way to represent alanguage in form of an abstract syntax tree and aninterpreter that uses the syntax tree to interpret languageconstructs.The part-whole relationship of the Composite patterncorresponds to the relationship of an expression and itssubexpressions in the Interpreter pattern.–The leaf is a terminal expression.–The composite is a non-terminal expression.– Evaluation of the components is interpretation of the syntax treeand its expressions.© Copyright 1995-2000 by <strong>Angelika</strong> <strong>Langer</strong>. All Rights Reserved.http://www.<strong>Angelika</strong><strong>Langer</strong>.com(39)last update: 11/7/2005 ,21:37The Interpreter PatternAbstract<strong>Expression</strong>Interpret()Terminal<strong>Expression</strong>Interpret()Nonterminal<strong>Expression</strong>list gInterpret()for all children:g->Interpret()© Copyright 1995-2000 by <strong>Angelika</strong> <strong>Langer</strong>. All Rights Reserved.http://www.<strong>Angelika</strong><strong>Langer</strong>.com(40)last update: 11/7/2005 ,21:37


21Example: Arithmetic <strong>Expression</strong>sSyntaxTree:– the representation of an arithmetic expression such as(a+1)*c or log(abs(x-N))Terminal:– a numerical literal such as a constant of type double– a reference to a variable of type double;its value might change between interpretations of theexpressionNonTerminal:– unary and binary expression consisting of one or twosubexpressions;– the expressions have different semantics such as +, -, *, /, ++, --, exp, log, sqrt© Copyright 1995-2000 by <strong>Angelika</strong> <strong>Langer</strong>. All Rights Reserved.http://www.<strong>Angelika</strong><strong>Langer</strong>.com(41)last update: 11/7/2005 ,21:37A Sample Syntax TreeNonTerminal(Binary: Product)(x+2)*3NonTerminal(Binary: Sum)Terminal(Literal: 3)Terminal(Variable: x)Terminal(Literal: 2)© Copyright 1995-2000 by <strong>Angelika</strong> <strong>Langer</strong>. All Rights Reserved.http://www.<strong>Angelika</strong><strong>Langer</strong>.com(42)last update: 11/7/2005 ,21:37


22OO Implementation à la GOFAbstractExprinterpret()TerminalExprinterpret()NonTerminalExprinterpret()Literalconst double vVariabledouble& vBinaryExprAbstractExpr* e1UnaryExprAbstractExpr* einterpret()interpret()AbstractExpr* e2interpret()v...vinterpret()SUMProductinterpret() interpret()... ...e1->interpret() + e2->interpret()e1->interpret() * e2->interpret()© Copyright 1995-2000 by <strong>Angelika</strong> <strong>Langer</strong>. All Rights Reserved.http://www.<strong>Angelika</strong><strong>Langer</strong>.com(43)last update: 11/7/2005 ,21:37The Abstract <strong>Expression</strong>sThe base classes that define the interface common to terminaland nonterminal expressions:class AbstractExpr {public:virtual double eval() const = 0;};class TerminalExpr : public AbstractExpr {};class NonTerminalExpr : public AbstractExpr {};© Copyright 1995-2000 by <strong>Angelika</strong> <strong>Langer</strong>. All Rights Reserved.http://www.<strong>Angelika</strong><strong>Langer</strong>.com(44)last update: 11/7/2005 ,21:37


23The Terminal <strong>Expression</strong>sclass Literal : public TerminalExpr {public:Literal(double v) : _val(v) {}double eval() const { return _val; }private:const double _val;};class Variable : public TerminalExpr {public:Variable(double& v) : _val(v) {}double eval() const { return _val; }private:double& _val;};© Copyright 1995-2000 by <strong>Angelika</strong> <strong>Langer</strong>. All Rights Reserved.http://www.<strong>Angelika</strong><strong>Langer</strong>.com(45)last update: 11/7/2005 ,21:37The Non-Terminal <strong>Expression</strong>sclass BinaryExpr : public NonTerminalExpr {protected:BinaryExpr(const AbstractExpr* e1, const AbstractExpr* e2): _expr1(e1),_expr2(e2) {}virtual ~BinaryExpr (){ delete const_cast(_expr1);delete const_cast(_expr2);}const AbstractExpr* _expr1;const AbstractExpr* _expr2;};class Sum : public BinaryExpr {public:Sum(const AbstractExpr* e1, const AbstractExpr* e2): BinExpr(e1,e2) {}double eval() const{ return _expr1->eval() + _expr2->eval(); }};© Copyright 1995-2000 by <strong>Angelika</strong> <strong>Langer</strong>. All Rights Reserved.http://www.<strong>Angelika</strong><strong>Langer</strong>.com(46)last update: 11/7/2005 ,21:37


24The ClientThe code that creates the syntax tree and initiates its recursiveinterpretation:NonTerminal(Binary: Product)(x+2)*3NonTerminal(Binary: Sum)Terminal(Literal: 3)Terminal(Variable: x)Terminal(Literal: 2)double x;Product expr(new Sum(new Variable(x),new Literal(2)),new Literal(3));cout


25Implementation Using <strong>Templates</strong>ExprT1, ExprT2, BinOpBinaryExprExprT1 e1ExprT2 e2BinOp opinterpret()op(e1.interpret(),e2.interpret())ExprT, , OpUnaryExprExprT e1Op opinterpret()op(e.interpret())«template argument»Literalconst double vinterpret()vVariabledouble& vinterpret()v«template argument»© Copyright 1995-2000 by <strong>Angelika</strong> <strong>Langer</strong>. All Rights Reserved.http://www.<strong>Angelika</strong><strong>Langer</strong>.com(49)last update: 11/7/2005 ,21:37The Terminal <strong>Expression</strong>sclass Literal {public:Literal(const double v) : _val(v) {}double eval() const { return _val; }private:const double _val;};class Variable {public:Variable(double& v) : _val(v) {}double eval() const { return _val; }private:double& _val;};© Copyright 1995-2000 by <strong>Angelika</strong> <strong>Langer</strong>. All Rights Reserved.http://www.<strong>Angelika</strong><strong>Langer</strong>.com(50)last update: 11/7/2005 ,21:37


26The Non-Terminal <strong>Expression</strong>stemplate class BinaryExpr {public:BinaryExpr(ExprT1 e1, ExprT2 e2,BinOp op=BinOp()): _expr1(e1),_expr2(e2),_op(op) {}double eval() const{ return _op(_expr1.eval(),_expr2.eval()); }private:ExprT1 _expr1;ExprT2 _expr2;BinOp _op;};As operations we can use the pre-defined STL function objects plus,minus, multiplies, divides, etc. or define our own functionsobjects as needed.© Copyright 1995-2000 by <strong>Angelika</strong> <strong>Langer</strong>. All Rights Reserved.http://www.<strong>Angelika</strong><strong>Langer</strong>.com(51)last update: 11/7/2005 ,21:37Creator FunctionsA binary expression representing a sum would be of typeBinExpr< ExprT1, ExprT2, plus >For convenience, define creator functions that take advantage ofautomatic template argument deduction for function templates:template BinaryExprmakeSum(ExprT1 e1, ExprT2 e2){ return BinaryExpr(e1,e2); }template BinaryExpr makeProd(ExprT1 e1, ExprT2 e2){ returnBinaryExpr(e1,e2); }© Copyright 1995-2000 by <strong>Angelika</strong> <strong>Langer</strong>. All Rights Reserved.http://www.<strong>Angelika</strong><strong>Langer</strong>.com(52)last update: 11/7/2005 ,21:37


27The ClientThe code that creates the syntax tree and initiates its recursiveinterpretation:NonTerminal(Binary: Product)(x+2)*3NonTerminal(Binary: Sum)Terminal(Literal: 3)Terminal(Variable: x)Terminal(Literal: 2)double x;BinaryExpr< BinaryExpr < Variable,Literal,plus >,Literal,multiplies >expr = makeProd (makeSum (Variable(x), Literal(2)),Literal(3));cout


28First attemptDefine the creator functions as overloaded operators:template BinaryExpr operator+(ExprT1 e1, ExprT2 e2){ return BinaryExpr (e1,e2); }An expression such as x+2 would evaluate toBinaryExpr (x,2)which is not exactly what we need. From just the type thecompiler cannot distinguish between a literal and a variableof type double. We need an binary expression that stores aVariable and a Literal expression internally.© Copyright 1995-2000 by <strong>Angelika</strong> <strong>Langer</strong>. All Rights Reserved.http://www.<strong>Angelika</strong><strong>Langer</strong>.com(55)last update: 11/7/2005 ,21:37Define variables as Variable expressions:double x; Variable v(x);cout


29SolutionInside the binary expression store constants of any numericaltype as Literal expressions.For this purpose define for each expression type and allnumerical types what their corresponding expression typeis:template struct exprTraits{ typedef ExprT expr_type; };template struct exprTraits{ typedef Literal expr_type; };template struct exprTraits{ typedef Literal expr_type; };...© Copyright 1995-2000 by <strong>Angelika</strong> <strong>Langer</strong>. All Rights Reserved.http://www.<strong>Angelika</strong><strong>Langer</strong>.com(57)last update: 11/7/2005 ,21:37Modify the Binary<strong>Expression</strong> ClassInside the binary expression convert expressions to theirexpression type as defined in the expression traits:template class BinaryExpr {public:BinaryExpr(ExprT1 e1, ExprT2 e2,BinOp op=BinOp()): _expr1(e1),_expr2(e2),_op(op) {}double eval() const{ return _op(_expr1.eval(),_expr2.eval()); }private:exprTraits::expr_type _expr1;exprTraits::expr_type _expr2;BinOp _op;};© Copyright 1995-2000 by <strong>Angelika</strong> <strong>Langer</strong>. All Rights Reserved.http://www.<strong>Angelika</strong><strong>Langer</strong>.com(58)last update: 11/7/2005 ,21:37


30Fine TuningDefine a helper function:template double eval(ExprT e) { return e.eval(); }In the exampledouble x; Variable v(x);cout


31InterpretationExprT2 ExprT1 Literaltmp2 =BinaryExpr ( tmp1 , 3.0 )eval( (v+2) * 3.0 )© Copyright 1995-2000 by <strong>Angelika</strong> <strong>Langer</strong>. All Rights Reserved.http://www.<strong>Angelika</strong><strong>Langer</strong>.com(61)last update: 11/7/2005 ,21:37Interpretationx2.0Variable(x).evaleval()+ Literal(2).evaleval()3.0tmp3 = tmp2.eval() = tmp1.evaleval()* Literal(3.0).evaleval()eval( (v+2) * 3.0 )© Copyright 1995-2000 by <strong>Angelika</strong> <strong>Langer</strong>. All Rights Reserved.http://www.<strong>Angelika</strong><strong>Langer</strong>.com(62)last update: 11/7/2005 ,21:37


33Incorporating FunctionsWe can incorporate functions such as sqrt(), exp(), etc.:template UnaryExprsqrt(const ExprT& e){return UnaryExpr(e,::std::sqrt);}and calculate the Gauss distribution:double sigma=2.0, mean=5.0;const double Pi = 3.141593;cout


34Further Applications in PracticeIf the interpret() or eval() function is provided as anoverloaded operator()(), the expressions can serve asfunction objects for the STL.list l;Identity x;count_if(l.begin(),l.end(), x >= 0 && x


35Run-Time PolymorphismClassic object-oriented approach:class Rotatable {public:virtual void rotate(int) = 0;};class Ellipse : public Rotatable{public:Ellipse(int x, int y): Xradius(x), Yradius(y) { }virtual void rotate(int);private: int Xradius,Yradius;};© Copyright 1995-2000 by <strong>Angelika</strong> <strong>Langer</strong>. All Rights Reserved.http://www.<strong>Angelika</strong><strong>Langer</strong>.com(69)last update: 11/7/2005 ,21:37Run-Time PolymorphismUsing run-time polymorphism:void vertical_flip(Rotatable& d){ d.rotate(180); }Ellipse ellipse(100,600);vertical_flip(ellipse);Rectangle rectangle(999,500);vertical_flip(rectangle);© Copyright 1995-2000 by <strong>Angelika</strong> <strong>Langer</strong>. All Rights Reserved.http://www.<strong>Angelika</strong><strong>Langer</strong>.com(70)last update: 11/7/2005 ,21:37


36Compile-Time PolymorphismReplace intrusive inheritance by name commonality:class Ellipse{public: Ellipse(intint x, int y): Xradius(x),Yradius(y) { }void rotate(intint);private:int Xradius,YradiusYradius;};class Rectangle {public: Rectangle(intx, int y): Xedge(x),Yedge(y) { }void rotate(intint);private:int Xedge, Yedge;};© Copyright 1995-2000 by <strong>Angelika</strong> <strong>Langer</strong>. All Rights Reserved.http://www.<strong>Angelika</strong><strong>Langer</strong>.com(71)last update: 11/7/2005 ,21:37Compile-Time PolymorphismUsing compile-time polymorphism:template void vertical_flip(Rotatable& d){ d.rotate(180); }Ellipse ellipse(100,600);vertical_flip(ellipse);Rectangle rectangle(999,500);vertical_flip(rectangle);© Copyright 1995-2000 by <strong>Angelika</strong> <strong>Langer</strong>. All Rights Reserved.http://www.<strong>Angelika</strong><strong>Langer</strong>.com(72)last update: 11/7/2005 ,21:37


37Run-Time vs. Compile-Time DispatchInheritance-based polymorphism (OOP) can be replaced bytemplates (GP = generic programming).Overhead:– GP: code bloat & compile-time overhead– OOP: run-time overheadConformance to an interface:– GP: common names– OOP: a common base classIntegration of built-in types:– GP: overloaded operators native operatorsfunction objects function pointers– OOP: not possible© Copyright 1995-2000 by <strong>Angelika</strong> <strong>Langer</strong>. All Rights Reserved.http://www.<strong>Angelika</strong><strong>Langer</strong>.com(73)last update: 11/7/2005 ,21:37! compile-time computation of constant values– factorial– square root! compile-time evaluation of expressions– dot product– arithmetic expression! more examples of modern template programming– compile-time polymorphism– policy classes– template meta-programmingAgenda© Copyright 1995-2000 by <strong>Angelika</strong> <strong>Langer</strong>. All Rights Reserved.http://www.<strong>Angelika</strong><strong>Langer</strong>.com(74)last update: 11/7/2005 ,21:37


38Policy Specifications! classic quick sort function from C library– uses function pointer for sorting criterionvoid qsort( void *base, size_t num, size_t width,int (*compare )(const void *elem1, const void *elem2 ));! sort algorithm from the <strong>C++</strong> library– uses comparitor type (function pointer or function object)templatevoid sort(RandomAccessIteratorfirst,RandomAccessIterator last,Comparator cmp);© Copyright 1995-2000 by <strong>Angelika</strong> <strong>Langer</strong>. All Rights Reserved.http://www.<strong>Angelika</strong><strong>Langer</strong>.com(75)last update: 11/7/2005 ,21:37The Strategy PatternThe Strategy pattern (also known as Policy) provides a way toconfigure a class or function (the context) with one of manybehaviors (the strategies).! There is a family of strategies that have a certain interfacein common.! The context uses this interface for implementing itsoperations.Examples:– allocation strategies of a container– sorting order used by a sort algorithm or a sorted collection– synchronization policy of objects© Copyright 1995-2000 by <strong>Angelika</strong> <strong>Langer</strong>. All Rights Reserved.http://www.<strong>Angelika</strong><strong>Langer</strong>.com(77)last update: 11/7/2005 ,21:37


39The Strategy PatternContextStrategy* sContextInterface()StrategyStrategyInterface()s->StrategyInterface()ConcreteStrategyStrategyInterface()ConcreteStrategyStrategyInterface()© Copyright 1995-2000 by <strong>Angelika</strong> <strong>Langer</strong>. All Rights Reserved.http://www.<strong>Angelika</strong><strong>Langer</strong>.com(78)last update: 11/7/2005 ,21:37An Example - Sorting of StringsContext:– a class or function that sorts strings, or– a sorted collectionStrategy:– ASCII sorting order– case-insensitive sorting order– culture-sensitive, dictionary sorting order© Copyright 1995-2000 by <strong>Angelika</strong> <strong>Langer</strong>. All Rights Reserved.http://www.<strong>Angelika</strong><strong>Langer</strong>.com(79)last update: 11/7/2005 ,21:37


40OO Implementation à la GOFSorterComparator* _cmpSorter(Comparator*)Comparatorlessthan()= 0sort()_cmp->lessthan()asciilessthan()caseinsensitivelessthan()culturesensitivelessthan()© Copyright 1995-2000 by <strong>Angelika</strong> <strong>Langer</strong>. All Rights Reserved.http://www.<strong>Angelika</strong><strong>Langer</strong>.com(80)last update: 11/7/2005 ,21:37The Contextclass Sorter{public:explicit Sorter(Comparator* c) : _cmp(c) {}void sort(const StringContainer& c){ ... _cmp->lessthan(lhs,rhs) ... }private:Comparator* _cmp;};© Copyright 1995-2000 by <strong>Angelika</strong> <strong>Langer</strong>. All Rights Reserved.http://www.<strong>Angelika</strong><strong>Langer</strong>.com(81)last update: 11/7/2005 ,21:37


41The Strategiesclass Comparator {public:virtual boollessthan(const string&, const string&) const = 0;};class Ascii : public Comparator {public:virtual boollessthan(const string& lhs, const string& rhs) const{ return lhs < rhs; }};© Copyright 1995-2000 by <strong>Angelika</strong> <strong>Langer</strong>. All Rights Reserved.http://www.<strong>Angelika</strong><strong>Langer</strong>.com(82)last update: 11/7/2005 ,21:37Using Context and StrategiesStringContainer cont;Ascii asciiCmp;CaseInsens caseInsCmp;Sorter asciiSrt(&asciiCmp);Sorter caseInsSrt(&caseInsCmp);asciiSrt.sort(cont);caseInsSrt.sort(cont);! cannot tell from the type of the Sorter how it sorts! need not re-compile Sorter when new strategies are added! run time binding for lessthan() based on type of comparator! polymorphism through “another level of indirection”© Copyright 1995-2000 by <strong>Angelika</strong> <strong>Langer</strong>. All Rights Reserved.http://www.<strong>Angelika</strong><strong>Langer</strong>.com(83)last update: 11/7/2005 ,21:37


42Implementation Using <strong>Templates</strong>SorterComparatorComparator _cmp«template argument»Sorter(Comparator)sort()_cmp.lessthan()asciilessthan()caseinsensitivelessthan()culturesensitivelessthan()© Copyright 1995-2000 by <strong>Angelika</strong> <strong>Langer</strong>. All Rights Reserved.http://www.<strong>Angelika</strong><strong>Langer</strong>.com(84)last update: 11/7/2005 ,21:37The Contexttemplate class Sorter{public:explicit Sorter(const Comparator& c = Comparator()): _cmp(c) {}void sort(const StringContainer& c){ ... _cmp.lessthan(lhs,rhs) ... }private:Comparator _cmp;};© Copyright 1995-2000 by <strong>Angelika</strong> <strong>Langer</strong>. All Rights Reserved.http://www.<strong>Angelika</strong><strong>Langer</strong>.com(85)last update: 11/7/2005 ,21:37


43The Strategiesclass Ascii {public:boollessthan(const string& lhs, const string& rhs) const{ return lhs < rhs; }};class CaseInsens {public:static boollessthan(const string& lhs, const string& rhs){ locale loc;const ctype& fac = use_facet(locloc);string tmp1(lhslhs),tmp2(),tmp2(rhsrhs);fac.tolowertolower(tmp1.begin(),tmp1.end());fac.tolowertolower(tmp2.begin(),tmp2.end());return tmp1 < tmp2;}};© Copyright 1995-2000 by <strong>Angelika</strong> <strong>Langer</strong>. All Rights Reserved.http://www.<strong>Angelika</strong><strong>Langer</strong>.com(86)last update: 11/7/2005 ,21:37The Strategiesclass CultSens {public:explicit CultSens(locale l = locale()) : _loc_loc(l) {}bool lessthan(const string& lhs, const string& rhs) const{ return _loc_loc(lhslhs,rhsrhs); }private:locale _loc_loc;};© Copyright 1995-2000 by <strong>Angelika</strong> <strong>Langer</strong>. All Rights Reserved.http://www.<strong>Angelika</strong><strong>Langer</strong>.com(87)last update: 11/7/2005 ,21:37


44Using Context and StrategiesStringContainer cont;Sorter srt1;Sorter srt2;Sorter srt3(CultSens(locale("German")));srt1.sort(cont);srt2.sort(cont);srt3.sort(cont);! can tell from the name of the type of the Sorter how it sorts! need to compile instantiations of Sorter for new strategies! compile time binding for sort() and lessthan()! polymorphism through templates© Copyright 1995-2000 by <strong>Angelika</strong> <strong>Langer</strong>. All Rights Reserved.http://www.<strong>Angelika</strong><strong>Langer</strong>.com(88)last update: 11/7/2005 ,21:37Evaluation of Policy Specifications! policy specification via template parameters is moreflexible– not restricted to just one function signature– both function pointers and function objects allowed– possibility for bundling policies© Copyright 1995-2000 by <strong>Angelika</strong> <strong>Langer</strong>. All Rights Reserved.http://www.<strong>Angelika</strong><strong>Langer</strong>.com(89)last update: 11/7/2005 ,21:37


45Examples from Standard <strong>C++</strong>! sorting strategy and allocation policy of containerstemplate class set;! character handling and allocation policy of stringstemplateclass basic_string;© Copyright 1995-2000 by <strong>Angelika</strong> <strong>Langer</strong>. All Rights Reserved.http://www.<strong>Angelika</strong><strong>Langer</strong>.com(90)last update: 11/7/2005 ,21:37! comparator type less from the STL– just one functionality provided– via overloaded function call operatorA Sorting Strategytemplate struct less : binary_function {};bool operator()(const T& x, const T& y) const;© Copyright 1995-2000 by <strong>Angelika</strong> <strong>Langer</strong>. All Rights Reserved.http://www.<strong>Angelika</strong><strong>Langer</strong>.com(91)last update: 11/7/2005 ,21:37


46A Policy Bundle! the standard allocator– a bundle of functionalities– provided as non-static member functionstemplate class allocator {public:...pointer allocate(size_t);void deallocate(T* p, size_t n);void construct(T* p, const T& val);void destroy(T* p);};© Copyright 1995-2000 by <strong>Angelika</strong> <strong>Langer</strong>. All Rights Reserved.http://www.<strong>Angelika</strong><strong>Langer</strong>.com(92)last update: 11/7/2005 ,21:37Another Policy Bundle! the standard character traits for type char– a bundle of static functionalitytemplatestruct char_traits {static bool eq(const char& c1, const char& c2);static bool lt(const char& c1, const char& c2);static char* move(char* s1, const char* s2, size_t n);static char* copy(char* s1, const char* s2, size_t n);...};© Copyright 1995-2000 by <strong>Angelika</strong> <strong>Langer</strong>. All Rights Reserved.http://www.<strong>Angelika</strong><strong>Langer</strong>.com(93)last update: 11/7/2005 ,21:37


47Alexandrescu’s Smart Pointer! the configurable smart pointer class templatefrom the Loki library– uses not just template type parameters, but also template templateparameterstemplateclass SmartPointer;© Copyright 1995-2000 by <strong>Angelika</strong> <strong>Langer</strong>. All Rights Reserved.http://www.<strong>Angelika</strong><strong>Langer</strong>.com(94)last update: 11/7/2005 ,21:37Alexandrescu’s Smart Pointer! ownership policy– deep copy, destructive copy, no copy– reference counted (thread-safe or not)! conversion policy– allow or disallow implicit conversion to underlying pointer type! checking policy– reject null– no check! storage policy– default storage (does delete )– array storage (does array delete[] )– heap storage (calls free())© Copyright 1995-2000 by <strong>Angelika</strong> <strong>Langer</strong>. All Rights Reserved.http://www.<strong>Angelika</strong><strong>Langer</strong>.com(95)last update: 11/7/2005 ,21:37


48Benefits of Meta-ProgrammingVery good performance due to! exclusive use of static binding;polymorphic behavior can be simulated statically.! inlining;enables the compiler to optimize aggressively.© Copyright 1995-2000 by <strong>Angelika</strong> <strong>Langer</strong>. All Rights Reserved.http://www.<strong>Angelika</strong><strong>Langer</strong>.com(108)last update: 11/7/2005 ,21:37Problems with Meta-Programming! Debugging.practically not possible; there are tricks though.! Error reporting.no influence on the compiler message.! Readability of code.it looks awkward.! Compilation times.increases by orders of magnitude.! Compiler limits.truncation of identifiers, loop limits exceeded.! Portability.some compilers still not support standard <strong>C++</strong>© Copyright 1995-2000 by <strong>Angelika</strong> <strong>Langer</strong>. All Rights Reserved.http://www.<strong>Angelika</strong><strong>Langer</strong>.com(109)last update: 11/7/2005 ,21:37


49<strong>Expression</strong> Template LibrariesReferencesThe Blitz Projecthttp://oonumerics.org/blitz/A <strong>C++</strong> class library for scientific computing which uses templatetechniques to achieve high performance.PETE (Portable <strong>Expression</strong> Template Engine)http://www.acl.lanl.gov/pete/A portable <strong>C++</strong> framework to easily add powerful expressiontemplates.© Copyright 1995-2000 by <strong>Angelika</strong> <strong>Langer</strong>. All Rights Reserved.http://www.<strong>Angelika</strong><strong>Langer</strong>.com(110)last update: 11/7/2005 ,21:37<strong>Expression</strong> Template LibrariesReferencesPOOMA (Parallel Object-Oriented Methods and Applications)http://www.acl.lanl.gov/pooma/– An object-oriented framework for applications in computationalscience requiring high-performance parallel computers.– Considerable success in real applications including gyrokinetic particle-incellplasma simulation and multimaterial compressible hydrodynamics.– Developed at Los Alamos National Laboratory, New Mexico.© Copyright 1995-2000 by <strong>Angelika</strong> <strong>Langer</strong>. All Rights Reserved.http://www.<strong>Angelika</strong><strong>Langer</strong>.com(111)last update: 11/7/2005 ,21:37


50Further LinksReferencesResearch Centre Jülichhttp://www.fz-juelich.de/zam/cxx/An impressive directory of <strong>C++</strong> resources such as books,articles, FAQs, other <strong>C++</strong> pages, compilers, libraries, etc.See in particular the links to other <strong>C++</strong> libraries athttp://www.fz-juelich.de/zam/cxx/extmain.html#lib© Copyright 1995-2000 by <strong>Angelika</strong> <strong>Langer</strong>. All Rights Reserved.http://www.<strong>Angelika</strong><strong>Langer</strong>.com(112)last update: 11/7/2005 ,21:37PatternsReferencesDesign PatternsErich Gamma, Richard Helm, Ralph Johnson, John VlissidesAddison-Wesley, 1994© Copyright 1995-2000 by <strong>Angelika</strong> <strong>Langer</strong>. All Rights Reserved.http://www.<strong>Angelika</strong><strong>Langer</strong>.com(115)last update: 11/7/2005 ,21:37


51Contact Info<strong>Angelika</strong> <strong>Langer</strong>Training & MentoringObject-Oriented Software Development in <strong>C++</strong> & JavaMunich, Germanyhttp: //www.<strong>Angelika</strong><strong>Langer</strong>.com© Copyright 1995-2000 by <strong>Angelika</strong> <strong>Langer</strong>. All Rights Reserved.http://www.<strong>Angelika</strong><strong>Langer</strong>.com(116)last update: 11/7/2005 ,21:37

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!