Bonjour,
Je code une classe représentant de nombres à virgule fixe. Du coup, j'ai rajouté des opérateurs arithmétiques ainsi que des constructeurs et opérateurs de conversion implicites.
Voici un code représentatif de ma classe telle qu'elle est actuellement (d'un point de vue API, l'implem est bidon) :
Je peux écrire du code comme ça, c'est cool :
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 template<typename T, std::uint8_t I = 7, std::uint8_t F = 24> class Number { public: Number() = default; template<typename U> Number(U value) : raw_data(value) { } Number(float value) : raw_data(value) { } operator float() const { return raw_data; } Number operator+(const Number& other) { Number result; result.raw_data = raw_data + other.raw_data; return result; } private: T raw_data; };
Par contre, je ne peux pas écrire ceci :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6 using Number = Number<std::uint32_t>; Number f = 2; Number g(3.14f); Number h = f + g; float j = h;
Je sais que pour réaliser ce genre d'opérations "mixed-mode", il faut faire des opérateurs amis. J'ai donc modifié mon opérateur + en ceci :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2 Number f = 2; Number i = f + 12;
Mais ce n'est pas suffisant, mon opérateur de conversion non 'explicit' fout visiblement la zouille :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5 friend Number operator+(const Number& lhs, const Number& rhs) { Number result; result.raw_data = lhs.raw_data + rhs.raw_data; return result; }
En le marquant comme 'explicit', le problème disparaît mais une erreur autre apparaît quand je fais float value = i;, naturellement... En faisait float value = static_cast<float>(i);, tout compile.error: ambiguous overload for 'operator+' (operand types are 'Number {aka Number<unsigned int>}' and 'int') Number i = h + 12; ~~^~~~ note: candidate: operator+(float, int) <built-in> note: candidate: Number<unsigned int> operator+(const Number<unsigned int>&, const Number<unsigned int>&)
Le problème est que j'ai passé l'opérateur + en tant qu'ami pour éviter de faire de convertir explicitement lors d'une addition (par exemple Number i = h + Number(12);) mais au final je me retrouve à avoir déplacer le casting. Je pense que la nouvelle situation est meilleure, il y aura moins de conversions explicites à faire. Mais bon le lait, le beurre, l'argent, la crémière tout ça, j'aimerais bien ne plus avoir de cast du tout
Une solution pour moi ?
Merci d'avance !
Partager