DÉCORER AVEC DES UNITÉS Séminaire technique Cours C++(++) 1.

Slides:



Advertisements
Présentations similaires
La boucle for : init7.c et init71.c
Advertisements

Les fonctions A quoi ça sert ?
A RECUPERER EN ENTRANT Le polycopié de Caml Partie 1
Rappels C.
Cours n° 7 Standard Template Library II.
Cours n° 8 Conception et Programmation à Objets
C.
Principes de programmation (suite)
OCaml - Les listes L3 MI.
Structures de données et algorithmes – TP2
Les méthodes en java Une méthode est un regroupement d’instructions ayant pour but de faire un traitement bien précis. Une méthode pour être utilisée.
Algorithmique et Programmation
Bibliothèque standard du C++
8PRO100 Éléments de programmation Allocation dynamique de la mémoire.
Introduction au paradigme objet Concepts importants surcharge (overload) redéfinition (override) Définition d’une classe Définition des attributs.
77 Utilisation des classes (suite). 7-2 Objectifs A la fin de ce cours, vous serez capables de : Définir des méthodes surchargées dans une classe Fournir.
Quest-ce quune classe dallocation? Une classe dallocation détermine la portée et la durée de vie dun objet ou dune fonction.
Base de programmation Script unity en c#.
Leçon 2 : Surcharge des opérateurs IUP 2 Génie Informatique Méthode et Outils pour la Programmation Françoise Greffier Université de Franche-Comté.
Les pointeurs Modes d’adressage de variables. Définition d’un pointeur. Opérateurs de base. Opérations élémentaires. Pointeurs et tableaux. Pointeurs et.
IFT-2000: Structures de données Les graphes Dominic Genest, 2009.
Programme de baccalauréat en informatique Programmation Orientée Objets IFT Thierry EUDE Module 7 : Classes et fonctions paramétrables Département.
66 Utilisation des classes et des objets. 6-2 Objectifs A la fin de ce cours, vous serez capables de : Créer de nouvelles classes à laide de Eclipse Utiliser.
Conteneurs STL.
1 PROTOTYPE PGC++ Vecteur_3D DÉFINITION. 2 class Vecteur_3D { private : float vx, vy, vz, vw; // Représentation en coordonnées homogènes. public : Vecteur_3D();
Contrôle de types Les types en programmation Expressions de types Un contrôleur de types Equivalence de types Conversions de types Généricité.
IFT 6800 Atelier en Technologies d’information
1 IFT 6800 Atelier en Technologies dinformation Le langage de programmation Java chapitre 3 : Classes et Objects.
Les arbres binaires.
1 La récursion. Nous avons vu qu'un programme est constitué d'un ensemble de fonctions. Il est possible pour une fonction donnée d'appeler une autre fonction.
Chapitre 9 Les sous-programmes.
COURS DE PROGRAMMATION ORIENTEE OBJET :
COURS DE PROGRAMMATION ORIENTEE OBJET :
1 Fonction : surcharge de sélection La surcharge de sélection consiste à implanter plusieurs méthodes de même nom dans une même classe à condition que.
Standard Template Library
C++ : fonctions et opérateurs
IFT-2000: Structures de données Piles et files Dominic Genest, 2009.
Structures de données IFT-2000
Récursion IFT1025: Programmation 2 Jian-Yun Nie. Définition Le fait pour un programme ou une méthode de s'appeler lui-même. Par exemple –Définir la notion.
Structures de données IFT-2000 Abder Alikacem Semaine 11 Gestion des arbres binaires de tri et de recherche. Les arbres cousus. Les arbres n-aires Département.
Procédures et fonctions
Plan cours La notion de pointeur et d’adresse mémoire.
La librairie assert.h.
Le langage C Structures de données
2.1 - Historique Chapitre 2 : Introduction au langage C++
La notion de type revisitée en POO
Variables et accès en Java. Déclaration des variables final transient static private Printer hp; transient => ne doivent pas être sérialisées volatile.
Un survol du language C.
1 Structures des données. 2  Le tableau permettait de désigner sous un seul nom un ensemble de valeurs de même type, chacune d'entre elles étant repérée.
Cours C++ Fonctions Surcharge d’opérateurs Passage d’arguments
Tutorat en bio-informatique
Les types composés Les enregistrements.
Les surcharges d'opérateurs
Le Préprocesseur. Sujets abordés: Préprocesseur –Qu’est ce? –Qu’est ce qu’une directive? Les macros –Les définir, les redéfinir, les dé-définir –Les macros.
Héritage H. Batatia. plan Notion (que signifie l’héritage) Ecriture en java Héritage multiple (interdit) Instanciation (partie propre et partie héritée)
Classe 1 CSI2572 Autres modificateurs de déclaration de variables: & volatile & register & static & auto & extern & const volatile Indique au compilateur.
Les classes Introduction aux Langages Orientés Objets
Cours 4 (14 octobre) Héritage. Chapitre III Héritage.
Conception de Programmes - IUT de Paris - 1ère année Conception de Programmes Objectifs et organisation du cours Introduction à la P.O.O.
8PRO107 Éléments de programmation Les adresses et les pointeurs.
8PRO107 Éléments de programmation Les tableaux. Étude de cas 1 Description du problème : Lire une liste d’entiers et l’afficher d’abord dans le même ordre.
PRO-1027 Programmation Scientifique en C
Les fractions
Conception de Programmes - IUT de Paris - 1ère année Les classes Introduction Déclaration d’une classe Utilisation d’une classe Définition des.
Introduction au langage C
BlueJ_III 1 Java, les objets : tout de suite ! Interaction entre objets Notes de cours associées au chapitre 3 tutorial BlueJ
PRÉSENTATION AGL LES TESTS LOGICIELS LES TEST LOGICIELS 1 Mickael BETTINELLI Brandon OZIOL Gaétan PHILIPPE Simon LUAIRE.
Informatique 2A Langage C 2 è séance. Objectifs de la séance 2 Début de la modularité avec les fonctions Création d’une première bibliothèque.
Transcription de la présentation:

DÉCORER AVEC DES UNITÉS Séminaire technique Cours C++(++) 1

Qu’allons nous voir? Première partie Pourquoi? Les autres librairies Units! Seconde partie Quelques notions de métaprogrammation Concept d’unités ScaledUnit PoweredUnit ComposedUnit Vector 2

Pourquoi ajouter des unités? // Calcule la distance, en mètre double CalculerDistance(double depart, double fin) { return fin – depart; } void main() { double start = 10.0; // En m double end = 50.0; // En km double dist = CalculerDistance(start, end); … } 3

Pourquoi ajouter des unités? // Calcule la distance, en mètre double CalculerDistance(double vitesse, double t) { return vitesse * t; } void main() { double start = 10.0; // En mètre double end = 50.0; // En mètre double dist = CalculerDistance(start, end); … } 4

// Calcule la distance, en mètre Metre CalculerDistance(Speed vitesse, Second t) { return vitesse * t; } … void main() { Metre start = 10.0; // En mètre Metre end = 50.0; // En mètre Metre dist = CalculerDistance(start, end); … } Pourquoi ajouter des unités? Erreur de compilation (Le plus clair possible) 5

// Calcule la distance, en mètre Metre CalculerDistance(Metre debut, Metre fin) { return fin - debut; } … void main() { Kilometre start = 10.0; // En kilomètre Kilometre end = 50.0; // En kilomètre Metre dist = CalculerDistance(start, end); … } Pourquoi ajouter des unités? Transformation automatique 6

Les autres librairies Boost::Unit OpenFrameworks Unités de Callum Grant 7

Boost::Units #include … quantity cm(4 * centi * meter); quantity m(4 * meter); quantity r1 = cm + m; cm contient 0.04 r1 contient

Boost::Units quantity cm(4 * centi * meter); quantity m(4 * meter); quantity a(4 * ampere); quantity c(2 * coulomb); quantity n(2 * newton); auto r2 = cm * m * a / (c * n); r2 contient 0.16 m.kg^-1.s quantity ::type, si::system> > r2 9

Boost::Units quantity cm(4 * centi * meter); quantity s(4 * second); auto r3 = cm + s; 22 erreurs de compilation 20 dans xstring et xutility. 10

Boost::Units Une dans boost : La spécialisation du modèle de fonction ‘add_typeof_helper, quantity >::type operator+(const quantity &, quantity &)’ a échoué. L’autre : ‘+’ binaire : ‘quantity ’ ne défini pas cet opérateur ou une conversion vers un type acceptable pour l’opérateur prédéfini er prix pour la clarté!

OpenFramework (Callum Grant) #include meters_by_second speed = cm(4) / s(4); auto result = cm(4) + s(4); // Erreur de compilation! ‘Util::Units::Internals::Convert ::checkConvertible’ utilise une struct de ‘Util::Units::Internals::static_assert2 ’ non défini. Hein??? 12

OpenFramework (Callum Grant) auto result = cm(4) * m(4) * A(4) / (C(2) * N(2)); cout<<result<<endl; 16 cm.m.A.(C.N)^-1 !?!?!?! 0.16 m.s.kg^-1 16 cm.s.kg^-1 13

Units! #include Metre m1 = Metre(4); Centimetre cm1 = Centimetre(4); Centimetre r1 = cm1 + m1; Speed r2 = cm1 / Second(2); auto r3 = cm1 + Second(4); // Erreur de compilation ‘+’ binaire : aucun opérateur trouvé qui accepte un opérande de partie droite de type ‘Second’ (ou il n’existe pas de conversion acceptable) 14

Units! Centimetre cm(4); Metre m(4); Ampere a(4); auto r2 = m * cm * a / (Coulomb(2) * Newton(2)); r2 contient 0.16 m.kg^-1.s Divide ::Type, Kilogram>::Type r2; ComposedUnit, PoweredUnit > r2; 15

Déclaration d’unité ScaledUnit Centimètre, Milliseconde, etc. struct metreBase; typedef standard ::Type Metre; typedef centi ::Type Centimetre; template struct standard { typedef ScaledUnit Type; }; template struct centi { typedef ScaledUnit Type; }; 16

Déclaration d’unité ScaledUnit Centimètre, Milliseconde, etc. struct secondBase; typedef standard ::Type Second; typedef ScaledUnit Minute; typedef ScaledUnit Hour; typedef ScaledUnit Day; 17

Déclaration d’unité PoweredUnit Centimètre carré, Seconde carré, etc. typedef PoweredUnit Centimetre2; typedef PoweredUnit SecondM2; 18

Déclaration d’unité ComposedUnit Newton (Kilogramme mètre par seconde carré), Coulomb, etc. typedef ComposedUnit, SecondM2> Newton; typedef Divide ::Type, Second2>::Type Newton; 19

Déclaration d’une nouvelle unité typedef ScaledUnit PiedDeRoi; typedef ScaledUnit Toise; typedef ScaledUnit PercheDuRoi; 20

Utilisation de la valeur d’une unité Pour faire le lien avec d’autres librairies Pour court-circuiter la validation du compilateur double val = Metre(4).Value(); 21

Où trouver la librairie? 22

NOTIONS DE MÉTAPROGRAMMATION 23

Rappel - Templates template class Foo { bool foo(T val1, T val2) { return val1 == val2; } } void main() { Foo iFoo; Foo dFoo; cout<<iFoo.foo(1,2)<<dFoo.foo(0.0,0.0)<<endl; } 24

Rappel - Templates template class Foo { bool foo(T val1, T val2) { return val1 == val2; } } template<> class Foo { bool foo(double val1, double val2) { return val1 != val2; } 25

Vérifier si deux types sont identiques template struct SameTypes { enum{ Result = 0 }; }; template struct SameTypes { enum{ Result = 1 }; }; 26 SameTypes ::Result

If Else Statique qui retourne des entiers template struct IfElseInt; template struct IfElseInt { enum { Result = T }; }; template struct IfElseInt { enum { Result = F }; }; 27

If Else Statique qui retourne des types template struct IfElseType; template struct IfElseType { typedef T Result; }; template struct IfElseType { typedef F Result; }; 28

CONCEPTS D’UNITÉS 29

Les constructeurs explicit Metre m = 5; Metre m2 = Metre(5); explicit Unit(const double val = 0.0) : m_value(val) { } 30 Erreur de compilation

Opération communes sur des unités Opérations logiques Addition/Soustraction Multiplication par une valeur sans unité Division (par la même unité ou une valeur sans unité) 31

Curiously Recurring Template Pattern Le nom de l’enfant est contenu dans le paramètre générique (template) du parent template class B { … }; class D : public B { … }; 32

Curiously Recurring Template Pattern template class Unit { … }; template<typename U, int N = 1, int D = 1, typename UBase = typename GetBaseUnit ::BaseUnit> class ScaledUnit : public Unit > { }; 33

Curiously Recurring Template Pattern Copy Constructeur Unit(const U& u) : m_value(u.m_value) { } 34

Curiously Recurring Template Pattern Opérations logiques bool operator==(const U& u) const { return m_value == u.m_value; } bool operator!=(const U& u) const { return !(*this == u); } … 35

Curiously Recurring Template Pattern Addition et soustraction U operator-(const U& u) const { return U(m_value - u.m_value); } U operator+(const U& u) const { return U(m_value + u.m_value); } 36

Curiously Recurring Template Pattern Multiplication et division U operator*(double u) const { return U(m_value * u); } Scalar operator/(const U& u) const { return Scalar(m_value / u.m_value); } 37

Trois types pour les unités ScaledUnit Centimètre, Milliseconde, etc. PoweredUnit Centimètre carré, Seconde carré, etc. ComposedUnit Newton (Kilogramme mètre par seconde carré), Coulomb, etc. Scalar! Sans unité 38

La classe ScaledUnit template<typename U, int N = 1, int D = 1, typename UBase = typename GetBaseUnit ::BaseUnit> class ScaledUnit : public Unit > { … }; 39

La classe PoweredUnit template<typename U, int N, int D = 1, typename UBase = typename GetBaseUnit ::BaseUnit> class PoweredUnit : public Unit > { … } 40

template struct GetBaseUnit { typedef U BaseUnit; }; template struct GetBaseUnit > { typedef SUBase BaseUnit; }; template struct GetBaseUnit > { typedef PUBase BaseUnit; }; 41 Utilitaire GetBaseUnit

La classe ComposedUnit template class ComposedUnit : public Unit > { … } 42

Conversion Centimetre cm(Decimetre(4)); 4 dm  40 cm Centimetre : ScaledUnit Decimetre : ScaledUnit (D To * N From ) / (N To * D From ) = Facteur (100 * 1) / (1 * 10) = From To

template struct GetScaleChange { static double Get() { return (static_cast (DT)* static_cast (NF)) / (static_cast (NT)* static_cast (DF)); } }; template struct GetScaleChange { static double Get() { return 1.0; } }; 44 Utilitaire GetScaleChange

Conversion Centimetre2 cm(Decimetre2(4)); 4 dm 2  400 cm 2 Centimetre2 : PoweredUnit Decimetre2 : PoweredUnit ((D To * N From ) / (N To * D From ))^(N Power /D Power ) = Facteur ((100 * 1) / (1 * 10))^(2/1) =

template struct GetChangeFactorBase { static double GetFactor() { return pow(GetScaleChange ::Get(), (N / static_cast (D))); } }; template struct GetChangeFactorBase { static double GetFactor() { return GetScaleChange ::Get(); } }; 46 Utilitaire GetChangeFactorBase

template struct ChangeFactor { … static double GetValue(double value) { return value * GetChangeFactorBase ::Num, GetScale ::Den, GetScale ::Num, GetScale ::Den, GetPower ::Num, GetPower ::Den>::GetFactor(); } }; 47 Utilitaire ChangeFactor

template struct GetScale { static const uint64 Num = 1; static const uint64 Den = 1; }; template struct GetScale > { static const uint64 Num = N * GetScale ::Num; static const uint64 Den = D * GetScale ::Den; }; template struct GetScale > { static const uint64 Num = GetScale ::Num; static const uint64 Den = GetScale ::Den; }; 48 Utilitaire GetScale

template struct GetPower { enum { Num = 1, Den = 1 }; template struct GetPower > { enum { Num = GetPower ::Num * N, Den = GetPower ::Den * D }; 49 Utilitaire GetPower

ScaledUnit 50

Constructeur template ScaledUnit(const ScaledUnit & u) : Unit >( ChangeFactor, ScaledUnit >::GetValue(u.Value()) ) { … } 51

Multiplication et division générale Unité * Unité = Unité 2 Unité / Unité = Sans Unité Unité * Unité N/D = Unité (N/D)+1 Unité * Unité -1 = Sans Unité Unité / Unité N/D = Unité (N/D)-1 Unité * Unité2 = Composition(Unité, Unité2) 52

Les traits template struct OperatorResultType { typedef ScaledUnit MultiplyType; typedef ScaledUnit DivideType; }; 53

Les traits template struct OperatorResultType > { typedef PoweredUnit, 2, 1, UBase> MultiplyType; typedef Scalar DivideType; }; 54

If Else Statique template struct IfElseType; template struct IfElseType { typedef T Result; }; template struct IfElseType { typedef F Result; }; 55

template struct OperatorResultType > { typedef typename IfElseType<PN + PD == 0, Scalar, PoweredUnit, PN + PD, PD, UBase> >::Result MultiplyType; typedef typename IfElseType<PD - PN == 0, Scalar, PoweredUnit, PD - PN, PD, UBase> >::Result DivideType; }; 56 Trait OperatorResultType avec PoweredUnit

Multiplication typename OperatorResultType >::MultiplyType operator*(const ScaledUnit & u) const { return typename OperatorResultType >::MultiplyType(Value() * u.Value()); } 57

Multiplication template typename OperatorResultType >::MultiplyType operator*(const ScaledUnit & u) const { typedef ChangeFactor, ScaledUnit > ChangeFactorType; return typename OperatorResultType >::MultiplyType(Value() * ChangeFactorType::GetValue(u.Value())); } 58

Multiplication template typename TransformUnit, ScaledUnit >::MultiplyType operator*(const ScaledUnit & u) const { typedef TransformUnit, ScaledUnit > TransformType; return TransformType::Multiply(*this, u); } 59

PoweredUnit Comme les ScaledUnit, avec des traits différents 60

Les traits template struct OperatorResultType > { typedef typename IfElseType<N + D == 0, Scalar, PoweredUnit >::Result MultiplyType; }; 61

template struct OperatorResultType >{ typedef typename IfElseType<(N*PD + D*PN) % (D*PD) == 0, typename IfElseType<(N*PD) + (D*PN) == 0, Scalar, typename IfElseType<(N*PD) + (PN*D) == (D*PD), U, PoweredUnit<U, ((N*PD) + (D*PN)) / (D*PD), 1, UBase> >::Result >::Result, PoweredUnit<U, ((N*PD) + (PN*D)) / PGCD ::Value, (D*PD) / PGCD ::Value, UBase> >::Result MultiplyType; }; 62 Trait OperatorResultType avec PoweredUnit

Calcul du PGCD template struct PGCD { enum { Value = PGCD ::Value }; }; template struct PGCD { enum { Value = M }; }; 63

ComposedUnit 64

Particularités On compose par la gauche ComposedUnit, C>, D> Pas besoin de traits comme les autres unités On va utiliser la structure « TransformUnit » Permet de combiner et simplifier des unités Metre.Kilogram.Second -2 == Kilogram.Metre.Second -2 Metre.Kilogram.Second -2 == Kilogram.Centimetre.Second -2 65

Utilisation de TransformUnit template typename TransformUnit, ScaledUnit >::MultiplyType operator*(const ScaledUnit & u) const { typedef TransformUnit, ScaledUnit > TransformType; return TransformType::Multiply(*this, u); } 66

template struct TransformUnit { typedef typename TransformBase ::ReturnTypeMultiply MultiplyType; typedef typename TransformBase ::ReturnTypeDivide DivideType; static MultiplyType Multiply(const U& u, const V& v) { return MultiplyType(u.Value() * (v.Value() * TransformBase ::GetChangeFactorMultiply())); } static DivideType Divide(const U& u, const V& v) { return DivideType(u.Value() / (v.Value() * TransformBase ::GetChangeFactorDivide())); } }; 67 Utilitaire TransformUnit

template struct TransformBase { typedef typename Transform ::ReturnTypeMultiply MultiplyResultType; typedef typename Transform ::ReturnTypeDivide DivideResultType; enum { FindMultiply = Transform ::Find, FindDivide = Transform ::Find }; typedef typename IfElseType<FindMultiply, MultiplyResultType, ComposedUnit >::Result ReturnTypeMultiply; typedef typename IfElseType<FindDivide, DivideResultType, ComposedUnit ::TypeReturn> >::Result ReturnTypeDivide; 68 Utilitaire TransformBase

… static double GetChangeFactorMultiply() { return Transform ::GetChangeFactor(); } static double GetChangeFactorDivide() { return Transform ::GetChangeFactor(); } }; 69 Utilitaire TransformBase

template struct TransformBase > { typedef typename TransformBase ::ReturnTypeMultiply IntermediateMultiplyType; typedef TransformBase MultiplyType; typedef typename MultiplyType::ReturnTypeMultiply ReturnTypeMultiply; enum { FindMultiply = MultiplyType::FindMultiply, … }; static double GetChangeFactorMultiply() { double f = TransformBase ::GetChangeFactorMultiply(); return MultiplyType::GetChangeFactorMultiply() * f; } }; 70 Utilitaire TransformBase avec ComposedUnit

template struct Transform; template struct Transform { typedef V ReturnTypeMultiply; typedef typename InversePower ::TypeReturn ReturnTypeDivide; enum { Find = 1 }; static double GetChangeFactor() { return 1.0; } }; 71 Utilitaire Transform

template struct Transform, V> { typedef typename ScaledUnit ::template OperatorResultType ::MultiplyType MultiplyResultType; enum { Find = SameTypes ::Result || SameTypes ::BaseUnit, UBase>::Result, VIsScalar = SameTypes ::Result }; typedef MultiplyResultType ReturnTypeMultiply; static double GetChangeFactor() { if (Find && !VIsScalar) return ChangeFactor, V>::GetFactor(); return 1.0; } }; 72 Utilitaire Transform

template struct Transform, V> { typedef typename Transform ::MultiplyResultType U1MultiplyType; typedef typename Transform ::MultiplyResultType U2MultiplyType; typedef typename ComposedUnit MultiplyResultTypeNoScalarFound; enum { Find = Transform ::Find || Transform ::Find || SameTypes, V>::Result }; static double GetChangeFactor() { double changeFactorU1 = Transform ::GetChangeFactor(); double changeFactorU2 = Transform ::GetChangeFactor(); return changeFactorU1 * changeFactorU2; } 73 Utilitaire Transform

// If we find a match // If (U1*V==Scalar) ResultType = U2 // elseif (U2*V==Scalar) ResultType = U1 // else ResultType = ComposedUnit // Otherwise, ResultType = ComposedUnit typedef typename IfElseType<SameTypes<Scalar, U1MultiplyType >::Result, U2, MultiplyResultTypeNoScalarFound>::Result FoundMultiplyTypeStep1; typedef typename IfElseType<SameTypes<Scalar, U2MultiplyType>::Result, U1, FoundMultiplyTypeStep1>::Result FoundMultiplyTypeStep2; typedef typename IfElseType<Find, FoundMultiplyTypeStep2, ComposedUnit >::Result ReturnTypeMultiply; typedef ReturnTypeMultiply MultiplyResultType; }; 74 Utilitaire Transform

Particularités Pas besoin de traits comme les autres unités On va utiliser la structure « TransformUnit » Metre.Kilogram.Second -2 == Kilogram.Metre.Second -2 Metre.Kilogram.Second -2 == Kilogram.Centimetre.Second -2 75

ComposedExactlyEqual template struct ComposedExactlyEqual; template struct ComposedExactlyEqual, ComposedUnit > { enum { Equal = ComposedEqual, ComposedUnit >::Find && ComposedEqual, ComposedUnit >::Find }; typedef typename IfElseType<Equal, ComposedUnit, ComposedUnit >::Result Type; }; 76

SFINAE Substitution Failure Is Not An Error Une erreur lors d’une spécialisation de template ne fait pas d’erreur de programmation! Tant qu’il y a au moins une spécialisation qui fonctionne, il n’y a pas d’erreur et la spécialisation est générée. Si ça ne fonctionne pas, aucune génération n’a lieu 77

SFINAE struct Test { typedef int foo; }; template void f(typename T::foo) { … } // Définition #1 template void f(T) { … } // Définition #2 int main() { f (10); // Appel #1. f (10); // Appel #2. Sans erreur (même s’il n’y a // pas de int::foo) grâce à SFINAE } 78

Permettre une méthode selon une condition template struct EnableIf { typedef T Type; }; template struct EnableIf {}; 79 Les structures ne contiennent pas la même interface! SFINAE!

template typename EnableIf, ComposedUnit >::Equivalent, ComposedUnit >::Type& operator=(const ComposedUnit & v) { double f = ComposedExactlyEqual, ComposedUnit >::GetChangeFactor(); Unit >::m_value = v.Value() * f; return *this; } 80 Assignation d’un ComposedUnit

Fonctions utilitaires template typename SqrtTransform ::TypeReturn sqrt(const Unit & u) { return SqrtTransform ::TypeReturn(sqrt(u.Value())); } template typename InversePower ::TypeReturn operator/(const double& d, const Unit & u) { return InversePower ::TypeReturn(d / u.Value()); } 81

template struct SqrtTransform { typedef PoweredUnit<U, 1, 2, typename GetBaseUnit ::BaseUnit> TypeReturn; }; 82 Utilitaire SqrtTransform

template struct SqrtTransform > { enum { RN = IfElseInt ::Result, RD = IfElseInt ::Result }; typedef typename IfElseType<RN == RD, U, PoweredUnit >::Result TypeReturn; }; 83 Utilitaire SqrtTransform

template struct SqrtTransform > { typedef ComposedUnit ::TypeReturn, typename SqrtTransform ::TypeReturn > TypeReturn; }; 84 Utilitaire SqrtTransform

template struct InversePower { typedef PoweredUnit<U, -1, 1, typename GetBaseUnit ::BaseUnit > TypeReturn; }; template<> struct InversePower { typedef Scalar TypeReturn; }; 85 Utilitaire InversePower

template struct InversePower > { typedef PoweredUnit TypeReturn; }; template struct InversePower > { typedef V TypeReturn; }; 86 Utilitaire InversePower

template struct InversePower > { typedef ComposedUnit ::TypeReturn, typename InversePower ::TypeReturn > TypeReturn; }; 87 Utilitaire InversePower

Vector 88

Vector Vecteur mathématique en 3 dimensions Fonctionne avec les unités Vector distance; Second time; Vector vSpeed = distance / time; 89

CONCLUSION Finalement! 90

Conclusion - Unités Ajoute une couche de validation à la compilation Plus besoin de se soucier des conversions Permet une interopérabilité entre différents systèmes (métrique et impérial) 91

Conclusion – C++ et généricité Sky is the limit! Façon différente de penser des algorithmes Se rapproche beaucoup des langages fonctionnels 92

QUESTIONS? 93