Bonsoir !
Je m'essaye depuis peu aux expression templates pour essayer de créer une petite classe pour gérer les vecteurs, plutôt dans un but didactique dans un premier temps, après je ferai des tests de performances voir si ça vaut le coup.
Bref, plutôt que d'embêter à chaque fois loulou avec des MP, je vais poster ici cette fois.
Donc j'ai une classe SVec3 minimale :
Je ne vous met pas toutes les définitions, juste le constructeur de copies :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 #include <boost/array.hpp> template <typename T> // Paramètre template class SVec3 { public: // Plusieurs constructeurs/destructeur SVec3 (); SVec3 (const T &, const T &, const T &); SVec3 (const SVec3 <T> &); ~SVec3 (); // Surcharges de l'opérateur [] en lecture et en écriture T operator [] (const size_t) const; T & operator [] (const size_t); private: boost::array <T, 3> values; // Tableau statique contenant trois éléments };
Ca marche parfaitement bien si j'instancie des SVec3 normalement. Par exemple SVec3 <double> vec1 (1.0, 1.0, 1.0); SVec3 <double> vec2 (vec1);
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6 // Constructeur de copie template <typename T> SVec3<T>::SVec3 (const SVec3 <T> & vec) : values (vec) { }
Là ça marche bien.
Maintenant je crée une classe Vec3 pour créer mes arbres (désolé si ma terminologie n'est pas bonne, j'essaye surtout de comprendre comment ça fonctionne, je crois que ça commence à rentrer mais pas encore la terminologie :p) :
Après avoir fait joujou avec quelqeus constructeurs (je sais qu'il manque le constructeur pour pouvoir instancié un Vec3 à partir une expression telle que A_Add <Vec3<T>, Vec3<T> >, je l'ai pas encore mise), si je fais :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36 #include "SVec3.hpp" // Inclut le fichier d'en-tête de la classe SVec3 template <typename T, typename Expr = SVec3 <T> > class Vec3 { public: // Plusieurs constructeurs/destructeur Vec3 (); Vec3 (const T &, const T &, const T &); Vec3 (Vec3 &); ~Vec3 (); // Surcharges de l'opérateur [] en lecture et en écriture T operator [] (const size_t) const; T & operator [] (const size_t); private: Expr myExpression; // Expression template. Par défaut : SVec3 <T> }; // Constructeur par défaut. Appelle le constructeur de myExpression. Par exemple, si // l'appel à Vec3 est celui-ci : Vec3 <double>, le deuxième paramètre template sera, // par défaut, SVec3 <double>, et donc le constructeur de SVec3 <double> sera appelé template <typename T, typename Expr> Vec3 <T, Expr>::Vec3 () : myExpression () { } // Constructeur. Celui-ci permet d'initialiser un vecteur avec trois valeurs template <typename T, typename Expr> Vec3 <T, Expr>::Vec3 (const T & x, const T & y, const T & z) : myExpression (x, y, z) { }
Vec3 <double> monVecteur; et que je regarde dans le profiler, ça m'instancie bien Vec3 <double>, puis ça m'appelle bien le constructeur de SVec3 puisque c'est le paramètre template par défaut pour Expr, ce qui m'initialise bien toutes mes valeurs à 0. Ca marche également si je fais :
Vec3 <double> monVecteur (1.0, 1.0, 1.0);
Le problème vient de mon constructeur de copie. Idéalement, je voudrais faire ceci :
Vec3 <double> monVecteur (1.0, 1.0, 1.0);
Vec3 <double> vec2 (monVecteur);
Et donc de ce fait j'ai codé mon constructeur comme ceci :
D'après moi, le deuxième appel est l'équivalent de ceci :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5 template <typename T, typename Expr> Vec3 <T, Expr>::Vec3 (Vec3 <T, Expr> & vec) : myExpression (vec.myExpression) { }
Vec3 <double, SVec3 <double> > vec2 (monVecteur);
// Constructeur :
Vec3 <T, Expr>::Vec3 <Vec3 <double, SVec3 <double> > & vec, ou SVec3 <double> est myExpression. Ca me paraissait logique donc d'écrire myExpression (vec.myExpression), ce qui, d'après moi aurait comme effet :
SVec3 <double> (vec.SVec3 <double>)...
Or le compilo n'a pas l'air de l'entendre comme ça :
J'avoue ne pas tellement comprendre, car même le message d'erreur semble me donner raison avec Expr = SVec3 <double>... Donc myExpression (vec.myExpression) == myExpression(vec.SVec3 <double> ).Vec3.hpp:46: instantiated from `Vec3<T, Expr>::Vec3(Vec3<T, Expr>&) [with T = double, Expr = SVec3<double>]'
SVec3.hpp:51: error: no matching function for call to `boost::array<double, 3u>::array(const SVec3<double>&)'
array.hpp:43: note: candidates are: boost::array<double, 3u>::array()
array.hpp:43: note: boost::array<double, 3u>::array(const boost::array<double, 3u>&)
:: === Build finished: 4 errors, 0 warnings ===
J'espère que je suis assez clair, sinon je peux toujours développer plus.
Merci de votre aide !
Partager