conversion implicite pour une classe template dans une comparaison surchargé

a marqué ce sujet comme résolu.

Hello, Je ne comprend pas comment fonctionne la conversion implicite.
mon prof fait dans son code :
auto m = expandMantissa<2M+1>(mantissa);//de type Unsigned<DigitType,2M+1>

static auto tooLarge = Unsigned<DigitType, M + 1>(1) << digits + 1;
DigitType est un type générique définis plus haut. Les deux objets sont de type Unsigned<T,size_t> avec des tailles size_t différentes.

Un peu plus loin dans son code, il fait if(m >= tooLarge), je veux avoir une conversion implicite ici avec le constructeur, afin que les opérateur de comparaison puissent fonctionner.

J’ai définis les operateur de comparaison, un constructeur pour passer de Unsigned<T,N> en Unsigned<T,M> Voici ce que j’ai dans ma classe Unsigned

De cette manière ça fonctionne, mais je ne suis pas satisfait avec tous les operateurs de comparaison en membre.

Initialement j’avais ma classe de la manière suivante ce que je trouvais beaucoup plus propre.

  1. Avec la V1, la conversion automatique n’est pas effectuée, je ne comprend pas pourquoi. Habituellement, je ne rend pas membre des fonctions qui n’ont pas besoins de l’être.
  2. J’ai aussi essayé avec tout les opérateurs en amis : friend, mais pas plus de succès.
  3. Si dans la V2 je n’indique pas que les méthodes sont constantes, la conversion auto n’est à nouveau pas appliquée.

Quels sont les règles pour que la conversion se passe automatiquement, quel organisation est la meilleur pour surcharger les opérateurs de comparaisons ? J’ai regardé par ici

[…] est une fonction libre et elle ne sera instanciée que si les arguments correspondent aux paramètres.

Mais ça n’explique pas le fait que le la disparition du const fasse disparaitre la conversion automatique ou je rate qqch ?

+0 -0

Le const dans la version amie ne devrait pas compiler. Cela n’a pas de sens.

Sinon, il me semblait qu’il y avait un vieille règle qui interdisait les conversion implicites en cas de template, mais non… ça compile: https://godbolt.org/z/4eGe6n Bizarre :/

Bref. L’écriture idéale jusqu’au C++17: les opérateurs amis définis inlines dans la définition de la classe histoire de les cacher. Et dans tes exemples, il manque le constructeur de conversion.

A partir du C++20, on définit le spaceship operator: https://godbolt.org/z/d5f56T

Le constructeur de conversion est Unsigned(const Unsigned<T,M>& other) : Unsigned<T,N>() { /*code*/} qui prend un type M en paramètre alors que la classe est de type N. Avec ça lorsque j’ai Unsigned<T,N> < Unsigned <T,M> un objet de type <T,N> est créé en utilisant le constructeur ci-dessus. Et je compare donc un T,N avec un T,N. Et j’ai définis l’opérateur de comparaison pour ces types.

Pour ce qui est du const sur les amis, j’ai raté mon copier coller, c’est corrigé

+0 -0

Au temps pour moi. Je dirais que l’on a des ambiguïtés maintenant. Il faut employer quel opérateur pour comparer maintenant? Celui qui passe vers du N ou celui vers du M?

Du coup, je ne vois guère de solution sans un opérateur qui prend T, M et N et s’occupe lui même de gérer les mixités.

Connectez-vous pour pouvoir poster un message.
Connexion

Pas encore membre ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte