Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

Precision sur l'operateur ternaire

4 réponses
Avatar
Aurelien Regat-Barrel
Bonjour a tous, et tout d'abord bonne annee 2007.

J'ai une question au sujet de l'opérateur ternaire, dans le contexte
suivant :

class A {};

class B : public A {};

class C : public A {};

int main()
{
A *a = ( true ) ? new B : new C;
}

je ne comprends pas pourquoi, avec VC++, j'ai droit a l'erreur:

error C2446: ':' : no conversion from 'C *' to 'B *'

Une idée ?

Merci.

--
Aurelien Regat-Barrel

4 réponses

Avatar
Michel Decima
Bonjour a tous, et tout d'abord bonne annee 2007.

J'ai une question au sujet de l'opérateur ternaire, dans le contexte
suivant :

class A {};

class B : public A {};

class C : public A {};

int main()
{
A *a = ( true ) ? new B : new C;
}

je ne comprends pas pourquoi, avec VC++, j'ai droit a l'erreur:

error C2446: ':' : no conversion from 'C *' to 'B *'

Une idée ?


Je ne me rappelle pas exactement des contraintes de type sur
les operandes de l'operateur ternaire, a part que ca se passe
mieux quand elles sont du meme type ;)

Dans le cas present, elle ne le sont pas : on a B* et C*.
Visiblement le compilateur ne determine pas tout seul le type
commun A* (il a surement de bonne raisons de ne pas le faire).
Il va falloir caster en A* pour que ca passe.

Avatar
James Kanze
Aurelien Regat-Barrel wrote:

J'ai une question au sujet de l'opérateur ternaire, dans le contexte
suivant :

class A {};

class B : public A {};

class C : public A {};

int main()
{
A *a = ( true ) ? new B : new C;
}

je ne comprends pas pourquoi, avec VC++, j'ai droit a l'erreur:

error C2446: ':' : no conversion from 'C *' to 'B *'


Parce que le compilateur ne peut pas convertir un C* en B*, ni
vice versa. Le type résultant d'une expression ?:, c'est
toujours le type d'une des sous expressions. Donc, ici, le
resultat du ?: peut être soit B*, soit C*. Sauf que les
conversions y manquent.

--
James Kanze (GABI Software) email:
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

Avatar
James Kanze
Michel Decima wrote:
J'ai une question au sujet de l'opérateur ternaire, dans le contexte
suivant :

class A {};

class B : public A {};

class C : public A {};

int main()
{
A *a = ( true ) ? new B : new C;
}

je ne comprends pas pourquoi, avec VC++, j'ai droit a l'erreur:

error C2446: ':' : no conversion from 'C *' to 'B *'

Une idée ?


Je ne me rappelle pas exactement des contraintes de type sur
les operandes de l'operateur ternaire, a part que ca se passe
mieux quand elles sont du meme type ;)


C'est ce que je conseille aussi. À quelques exceptions près (par
exemple, si une des deux est une expression de throw).

Dans le cas present, elle ne le sont pas : on a B* et C*.
Visiblement le compilateur ne determine pas tout seul le type
commun A* (il a surement de bonne raisons de ne pas le faire).


La bonne raison qu'a le compilateur, c'est que la spécification
du langage l'interdit:-). La raison que la spécification du
langage l'interdit est plus complexe, mais déjà, on pourrait se
poser la question : pourquoi A*, et non void* ? Dans d'autres
cas, c'est encore moins clairs :

struct B1 {} ; struct B2 {} ;
struct D1 : B1, B2 {} ;
struct D2 : B1, B2 {} ;

... cond ? new D1 : new D2 ;

Dans certains cas, on pourrait se baser sur la contexte :

B1* p = cond ? new D1 : new D2 ;

Mais baser sur la contexte ne va pas sans poser de problèmes, et
la contexte n'est pas toujours là, non plus.

--
James Kanze (GABI Software) email:
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34


Avatar
Aurelien Regat-Barrel
Ok, merci a vous deux.

C'est donc bien une restriction du langage. Le cast en (A*) était déja
présent a l'origine, j'ai modifié le code pour utiliser un if...

--
Aurelien Regat-Barrel