4 votes

"if (var)" utilise une conversion en nombre au lieu de boolean

Pourquoi si (var) ... utilise une conversion de nombre au lieu de boolean ? J'ai une classe qui implémente les deux :

operator int() { ....}
operator bool() { ....}

mais si j'utilise :

if (my_class_var) ....;

alors la conversion int est utilisée à la place de boolean ?!!?!

EDIT: Comme le dit versedmarald, c'est correct. J'ai trouvé quelle était la différence.. En fait, j'utilise :

operator int() { ....}
operator bool() const { ... }

Toujours fasciné, pourquoi la différence ? gcc version 4.6.2

3voto

jogojapan Points 26661

Si ce que vous dites est vrai, je crois que votre compilateur enfreint la norme :

(§6.4/4) La valeur d'une condition qui est une déclaration initialisée dans une instruction autre qu'une instruction switch est la valeur de la variable déclarée convertie de manière contextuelle en booléen (Clause 4). Si cette conversion est mal formée, le programme est mal formée. [...]

(Pour être clair, cela se situe dans le contexte de la section §6.4, qui décrit les instructions if et switch.)

1voto

verdesmarald Points 6632

Il ne le fait pas (au moins en utilisant g++). Je suppose qu'il y a une erreur dans vos opérateurs de conversion.

#include 
class A {
public:
    operator int() { return 1; }
};

class B {
public:
    operator int() { return 1; }
    operator bool() { return false; }
};

int main() {
    A a;
    B b;

    if (a)
        std::cout << "true\n";
    else
        std::cout << "false\n";

    if (b)
        std::cout << "true\n";
    else
        std::cout << "false\n";
}

Résultats :

true
false

1voto

ForEveR Points 28133

Il existe deux chaînes de conversion implicite définies par l'utilisateur.

Première - classe -> bool -> pas de conversion

Deuxième - classe -> int -> bool

n3337 4/2

Remarque : les expressions d'un certain type seront implicitement converties en d'autres types dans plusieurs contextes :

— Lorsqu'elles sont utilisées dans la condition d'une instruction if ou d'une boucle (6.4, 6.5). Le type de destination est bool.

n3337 4/3

L'effet de toute conversion implicite est le même que d'effectuer la déclaration, l'initialisation puis d'utiliser la variable temporaire comme résultat de la conversion.

Les guillemets signifient cela vraiment

if (class_var) 

est

if (bool _ = class_var)

n3337 13.3.3/1

Étant donné ces définitions, une fonction viable F1 est définie comme étant une meilleure fonction qu'une autre fonction viable F2 si pour tous les arguments i, ICSi(F1) n'est pas une séquence de conversion pire que ICSi(F2), et ensuite

— le contexte est une initialisation par une conversion définie par l'utilisateur (voir 8.5, 13.3.1.5 et 13.3.1.6) et la séquence de conversion standard du type de retour de F1 vers le type de destination (c'est-à-dire le type du l'entité en cours d'initialisation) est une meilleure séquence de conversion que la séquence de conversion standard de le type de retour de F2 vers le type de destination. [ Exemple :

struct A {
A();
operator int();
operator double();
} a;
int i = a; // a.operator int() suivi d'aucune conversion
// est meilleur que a.operator double() suivi de
// une conversion en int
float x = a; // ambigu : les deux possibilités nécessitent des conversions,
// et aucune n'est meilleure que l'autre

— fin d'exemple

Donc, le compilateur devrait choisir operator bool, car classe -> bool -> pas de conversion standard est meilleur que classe -> int -> conversion standard en bool

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X