#include #define SIZE_PVECTOR_TAB 50 struct PVector{ // Définition des types iterateurs typedef double* Iterator; typedef const double* ConstIterator; // Fonctions de récupération des itérateurs de début et de fin Iterator begin(){return p_elements;} Iterator end(){return p_elements + SIZE_PVECTOR_TAB;} ConstIterator begin()const{return p_elements;} ConstIterator end()const{return p_elements + SIZE_PVECTOR_TAB;} void setValue(double val){ for(Iterator it = begin(); it != end(); ++it){ *it = val; } } template const PVector& operator = (T expr); // Et enfin les données double p_elements[SIZE_PVECTOR_TAB]; }; //Surcharge de l'opérateur d'affectation = template const PVector& PVector::operator = (T expr){ for(Iterator i = begin(); i != end(); ++i, ++expr){ *i = *expr; } return *this; } //Nos opérateurs enum Operators{ Add, // addition Sub, // soustraction Mult, // multiplication Div, // division Plus, // + unaire Minus, // - unaire Const // Constante }; //des opérateurs unitaires // Modèle de classe pour nos opérateurs unaires template struct UnaryOp {}; // Classe de base pour nos opérateurs unaires template struct UnaryOpBase{ UnaryOpBase(T t) : It(t) {} inline void operator ++(){++It;} T It; }; // Spécialisation pour le moins unaire - nous devrons spécialiser nos classes pour chaque opérateur template struct UnaryOp : public UnaryOpBase{ UnaryOp(T t) : UnaryOpBase(t){} inline double operator *(){return -(*UnaryOpBase::It);} }; // Spécialisation pour les constantes template struct UnaryOp : public UnaryOpBase{ UnaryOp(T t) : UnaryOpBase(t) {} inline void operator ++(){} inline double operator *(){return UnaryOpBase::It;} }; // Modèle de classe pour nos opérateurs binaires template struct BinaryOp{ inline double operator *(){return UnaryOpBase::It;} }; // Classe de base pour nos opérateurs binaires template struct BinaryOpBase{ BinaryOpBase(T I1, U I2) : It1(I1), It2(I2) {} inline void operator ++(){++It1; ++It2;} inline double operator *(){return *It1 + *It2;} T It1; U It2; }; // Spécialisation pour l'addition template struct BinaryOp : public BinaryOpBase{ BinaryOp(T I1, U I2) : BinaryOpBase(I1, I2){} inline double operator *() {return *BinaryOpBase::It1 + *BinaryOpBase::It2;} }; // Spécialisation pour la multiplication template struct BinaryOp : public BinaryOpBase{ BinaryOp(T I1, U I2) : BinaryOpBase(I1, I2){} inline double operator *() {return *BinaryOpBase::It1 * *BinaryOpBase::It2;} }; //Spécialisation pour la division template struct BinaryOp : public BinaryOpBase{ BinaryOp(T I1, U I2) : BinaryOpBase(I1, I2){} inline double operator *() {return *BinaryOpBase::It1 - *BinaryOpBase::It2;} }; // Spécialisation pour la division template struct BinaryOp : public BinaryOpBase{ BinaryOp(T I1, U I2) : BinaryOpBase(I1, I2){} inline double operator * () {return *BinaryOpBase::It1 / *BinaryOpBase::It2;} }; //arbre générer par le compilateur // BinaryOp,Div>,BinaryOp,UnaryOp,Mult>,Minus>; //fonctions qui permettent de simplifier la surcharge des opérateurs template inline BinaryOp MakeAdd(const T& t, const U& u){ return BinaryOp(t, u); } template inline BinaryOp MakeSub(const T& t, const U& u){ return BinaryOp(t, u); } template inline BinaryOp MakeMult(const T& t, const U& u){ return BinaryOp(t, u); } template inline BinaryOp MakeDiv(const T& t, const U& u){ return BinaryOp(t, u); } template inline UnaryOp MakeMinus(const T& t){ return UnaryOp(t); } template inline UnaryOp MakeConst(const T& t){ return UnaryOp(t); } //Surcharge des opérateurs //Surcharge de l'opérateur + template BinaryOp operator +(const T& v1, const U& v2){ return MakeAdd(v1, v2); } template BinaryOp operator +(const PVector& v1, const T& v2){ return MakeAdd(v1.begin(), v2); } template BinaryOp operator +(const T& v1, const PVector& v2){ return MakeAdd(v1, v2.begin()); } BinaryOp operator +(const PVector& v1, const PVector& v2){ return MakeAdd(v1.begin(), v2.begin()); } //surcharge de l'opérateur - (pour v1 - v2) template BinaryOp operator - (const T& v1, const U& v2){ return MakeSub(v1, v2); } BinaryOp operator - (const PVector& v1, const PVector& v2){ return MakeSub(v1.begin(), v2.begin()); } //Surcharge de l'opérateur * template BinaryOp, Mult> operator * (const T& v1, double d){ return MakeMult(v1, MakeConst(d)); } BinaryOp, Mult> operator * (const PVector& v1, double d){ return MakeMult(v1.begin(), MakeConst(d)); } //Surcharge de l'opéateur / BinaryOp, Div> operator / (const PVector& v1, double d){ return MakeDiv(v1.begin(), MakeConst(d)); } // Surcharge de l'opérateur - (pour -PVector) template UnaryOp operator - (const T& v1){ return MakeMinus(v1); } UnaryOp operator - (const PVector& v1){ return MakeMinus(v1.begin()); } using namespace std; int main(int argc, char **argv) { cout << "Hello, world!" << endl; PVector v1, v2, v3, v4; v1.setValue(1.0); v2.setValue(1.0); v3.setValue(1.0); v4 = (v1 / 2.0) - (v2 + v3) * 2.0; cout << "v4 = (" << v4.p_elements[0] << ", " << v4.p_elements[1] << ", " << v4.p_elements[2] << ")" << endl; cout << "On doit avoir (-3.5, -3.5, -3.5)" << endl; return 0; }