Je ne sais pas en ce qui concerne les autres, mais je m'en sers assez
librement.
Si l'idée importante derrière un bout de code, c'est que la
valeur x soit affectée, et non qu'on a une condition, je le trouve plus
claire d'écrire :
x = ( condition
? a
: b ) ;
que :
if ( condition ) {
x = a ;
} else {
x = b ;
}
Je ne sais pas en ce qui concerne les autres, mais je m'en sers assez
librement.
Si l'idée importante derrière un bout de code, c'est que la
valeur x soit affectée, et non qu'on a une condition, je le trouve plus
claire d'écrire :
x = ( condition
? a
: b ) ;
que :
if ( condition ) {
x = a ;
} else {
x = b ;
}
Je ne sais pas en ce qui concerne les autres, mais je m'en sers assez
librement.
Si l'idée importante derrière un bout de code, c'est que la
valeur x soit affectée, et non qu'on a une condition, je le trouve plus
claire d'écrire :
x = ( condition
? a
: b ) ;
que :
if ( condition ) {
x = a ;
} else {
x = b ;
}
En tous cas, sur mon compilateur,
std::cout<<(0?3:4.567);
retourne 4.567 et non pas 4 (comme ce serai le cas avec une conversion
en int)
En tous cas, sur mon compilateur,
std::cout<<(0?3:4.567);
retourne 4.567 et non pas 4 (comme ce serai le cas avec une conversion
en int)
En tous cas, sur mon compilateur,
std::cout<<(0?3:4.567);
retourne 4.567 et non pas 4 (comme ce serai le cas avec une conversion
en int)
En tous cas, sur mon compilateur,
std::cout<<(0?3:4.567);
retourne 4.567 et non pas 4 (comme ce serai le cas avec une conversion
en int)
verifie le code assembleur genere par le compilateur, il sais a la
compilation que le test est tjs faux il remplace ca directement par 4.56
enfin sous visual
C'est beaucoup plus simple que ça. Il s'agit d'une expression
En tous cas, sur mon compilateur,
std::cout<<(0?3:4.567);
retourne 4.567 et non pas 4 (comme ce serai le cas avec une conversion
en int)
verifie le code assembleur genere par le compilateur, il sais a la
compilation que le test est tjs faux il remplace ca directement par 4.56
enfin sous visual
C'est beaucoup plus simple que ça. Il s'agit d'une expression
En tous cas, sur mon compilateur,
std::cout<<(0?3:4.567);
retourne 4.567 et non pas 4 (comme ce serai le cas avec une conversion
en int)
verifie le code assembleur genere par le compilateur, il sais a la
compilation que le test est tjs faux il remplace ca directement par 4.56
enfin sous visual
C'est beaucoup plus simple que ça. Il s'agit d'une expression
En tous cas, sur mon compilateur,
std::cout<<(0?3:4.567);
retourne 4.567 et non pas 4 (comme ce serai le cas avec une
conversion en int)
verifie le code assembleur genere par le compilateur, il sais a la
compilation que le test est tjs faux il remplace ca directement par
4.56 enfin sous visual
En tous cas, sur mon compilateur,
std::cout<<(0?3:4.567);
retourne 4.567 et non pas 4 (comme ce serai le cas avec une
conversion en int)
verifie le code assembleur genere par le compilateur, il sais a la
compilation que le test est tjs faux il remplace ca directement par
4.56 enfin sous visual
En tous cas, sur mon compilateur,
std::cout<<(0?3:4.567);
retourne 4.567 et non pas 4 (comme ce serai le cas avec une
conversion en int)
verifie le code assembleur genere par le compilateur, il sais a la
compilation que le test est tjs faux il remplace ca directement par
4.56 enfin sous visual
James Kanze typa:"heinquoi" <nospam* writes:
|> j'ai dans un exemple un programme qui contient la ligne :
|> cout << endl << "le nombre 11 etait " << (b2 ? "TROUVE" : "NON TROUVE") <<
|> endl;
|> je intéresse surtout à (b2 ? "TROUVE" : "NON TROUVE") est ce que
|> opérateur évaluation "?" est un vestige de C ?
Dans le même sens que l'opérateur de '+' est un vestige de C ?
|> si je remplace ce morceau par ( if b2 "TROUVE" else "NON TROUVE")
|> cela ne fonctionne pas, pourtant il s'agit d'evaluation sur b2
|> hormis le fait que cette écriture lorsqu'elle est fréquente est
|> obscure et limite 'incantatoire' qu'elle est sont intérêt et
|> pourquoi fonctionne t elle ou un if ne fonctionne pas?
Parce qu'un if, c'est une instruction de contrôle de flux, et ?:,
c'est un opérateur. On aurait pu imaginer qu'le même syntaxe sert
dans les deux cas, mais ce n'est pas le cas en C ni en C++ (ni en
Java, ni en Objective C, ni en ...).
Je ne sais pas en ce qui concerne les autres, mais je m'en sers assez
librement. Si l'idée importante derrière un bout de code, c'est que
la valeur x soit affectée, et non qu'on a une condition, je le trouve
plus claire d'écrire :
x = ( condition
? a
: b ) ;
que :
if ( condition ) {
x = a ;
} else {
x = b ;
}
Et si c'est:
int x = (condition ? a : b);
il faudrait faire:
int x;
if(condition)
{
x = a;
}
else
{
x = b;
}
Ça va plus loin, l'opérateur ? pouvant s'utiliser à la place d'une
rvalue (éventuellement temporaire), on arrive à des écritures à la
fois plus compactes et pour moi plus lisibles :
y = fonct(10, (condition ? a : b));
ou l'exemple de la question de départ:
std::cout << (condition ? "VRAI" : "FAUX") << std::endl;
En revanche, et bien que ce soit possible semble-t-il, remplacer un if
par un ? me paraît non naturel et à éviter :
(condition ? std::cout<<100 : std::cout<<200); //NON
Je veux dire par là que si le but est l'évaluation et non
l'affectation, le if() est LA solution.
James Kanze <kanze@gabi-soft.fr> typa:
"heinquoi" <nospam*heinquoi1@libertysurf.fr> writes:
|> j'ai dans un exemple un programme qui contient la ligne :
|> cout << endl << "le nombre 11 etait " << (b2 ? "TROUVE" : "NON TROUVE") <<
|> endl;
|> je intéresse surtout à (b2 ? "TROUVE" : "NON TROUVE") est ce que
|> opérateur évaluation "?" est un vestige de C ?
Dans le même sens que l'opérateur de '+' est un vestige de C ?
|> si je remplace ce morceau par ( if b2 "TROUVE" else "NON TROUVE")
|> cela ne fonctionne pas, pourtant il s'agit d'evaluation sur b2
|> hormis le fait que cette écriture lorsqu'elle est fréquente est
|> obscure et limite 'incantatoire' qu'elle est sont intérêt et
|> pourquoi fonctionne t elle ou un if ne fonctionne pas?
Parce qu'un if, c'est une instruction de contrôle de flux, et ?:,
c'est un opérateur. On aurait pu imaginer qu'le même syntaxe sert
dans les deux cas, mais ce n'est pas le cas en C ni en C++ (ni en
Java, ni en Objective C, ni en ...).
Je ne sais pas en ce qui concerne les autres, mais je m'en sers assez
librement. Si l'idée importante derrière un bout de code, c'est que
la valeur x soit affectée, et non qu'on a une condition, je le trouve
plus claire d'écrire :
x = ( condition
? a
: b ) ;
que :
if ( condition ) {
x = a ;
} else {
x = b ;
}
Et si c'est:
int x = (condition ? a : b);
il faudrait faire:
int x;
if(condition)
{
x = a;
}
else
{
x = b;
}
Ça va plus loin, l'opérateur ? pouvant s'utiliser à la place d'une
rvalue (éventuellement temporaire), on arrive à des écritures à la
fois plus compactes et pour moi plus lisibles :
y = fonct(10, (condition ? a : b));
ou l'exemple de la question de départ:
std::cout << (condition ? "VRAI" : "FAUX") << std::endl;
En revanche, et bien que ce soit possible semble-t-il, remplacer un if
par un ? me paraît non naturel et à éviter :
(condition ? std::cout<<100 : std::cout<<200); //NON
Je veux dire par là que si le but est l'évaluation et non
l'affectation, le if() est LA solution.
James Kanze typa:"heinquoi" <nospam* writes:
|> j'ai dans un exemple un programme qui contient la ligne :
|> cout << endl << "le nombre 11 etait " << (b2 ? "TROUVE" : "NON TROUVE") <<
|> endl;
|> je intéresse surtout à (b2 ? "TROUVE" : "NON TROUVE") est ce que
|> opérateur évaluation "?" est un vestige de C ?
Dans le même sens que l'opérateur de '+' est un vestige de C ?
|> si je remplace ce morceau par ( if b2 "TROUVE" else "NON TROUVE")
|> cela ne fonctionne pas, pourtant il s'agit d'evaluation sur b2
|> hormis le fait que cette écriture lorsqu'elle est fréquente est
|> obscure et limite 'incantatoire' qu'elle est sont intérêt et
|> pourquoi fonctionne t elle ou un if ne fonctionne pas?
Parce qu'un if, c'est une instruction de contrôle de flux, et ?:,
c'est un opérateur. On aurait pu imaginer qu'le même syntaxe sert
dans les deux cas, mais ce n'est pas le cas en C ni en C++ (ni en
Java, ni en Objective C, ni en ...).
Je ne sais pas en ce qui concerne les autres, mais je m'en sers assez
librement. Si l'idée importante derrière un bout de code, c'est que
la valeur x soit affectée, et non qu'on a une condition, je le trouve
plus claire d'écrire :
x = ( condition
? a
: b ) ;
que :
if ( condition ) {
x = a ;
} else {
x = b ;
}
Et si c'est:
int x = (condition ? a : b);
il faudrait faire:
int x;
if(condition)
{
x = a;
}
else
{
x = b;
}
Ça va plus loin, l'opérateur ? pouvant s'utiliser à la place d'une
rvalue (éventuellement temporaire), on arrive à des écritures à la
fois plus compactes et pour moi plus lisibles :
y = fonct(10, (condition ? a : b));
ou l'exemple de la question de départ:
std::cout << (condition ? "VRAI" : "FAUX") << std::endl;
En revanche, et bien que ce soit possible semble-t-il, remplacer un if
par un ? me paraît non naturel et à éviter :
(condition ? std::cout<<100 : std::cout<<200); //NON
Je veux dire par là que si le but est l'évaluation et non
l'affectation, le if() est LA solution.
MaClasse::MaClasse(
int param1,
int param2 )
: MaBase( param1 > param2 ? param1 : param2 )
{
}
Dans ces cas-là, on n'a de toute façon pas le choix.
MaClasse::MaClasse(
int param1,
int param2 )
: MaBase( param1 > param2 ? param1 : param2 )
{
}
Dans ces cas-là, on n'a de toute façon pas le choix.
MaClasse::MaClasse(
int param1,
int param2 )
: MaBase( param1 > param2 ? param1 : param2 )
{
}
Dans ces cas-là, on n'a de toute façon pas le choix.
On 23 Jun 2004 23:44:54 +0200, James Kanze :Si l'idée importante derrière un bout de code, c'est que la valeur x
soit affectée, et non qu'on a une condition, je le trouve plus claire
d'écrire :
x = ( condition
? a
: b ) ;
J'aimerais savoir ce que tu penses de :
ifstream fichier (condition ? "input1.txt" : "input2.txt");
Je précise ma question : le fait de se passer d'une variable
"nom_de_fichier" (ce qui est rendu possible par le fait qu'on utilise
"?:" et pas "if") est-il (d'après toi) un élément de clarification ou
d'obfuscation ?
On 23 Jun 2004 23:44:54 +0200, James Kanze <kanze@gabi-soft.fr>:
Si l'idée importante derrière un bout de code, c'est que la valeur x
soit affectée, et non qu'on a une condition, je le trouve plus claire
d'écrire :
x = ( condition
? a
: b ) ;
J'aimerais savoir ce que tu penses de :
ifstream fichier (condition ? "input1.txt" : "input2.txt");
Je précise ma question : le fait de se passer d'une variable
"nom_de_fichier" (ce qui est rendu possible par le fait qu'on utilise
"?:" et pas "if") est-il (d'après toi) un élément de clarification ou
d'obfuscation ?
On 23 Jun 2004 23:44:54 +0200, James Kanze :Si l'idée importante derrière un bout de code, c'est que la valeur x
soit affectée, et non qu'on a une condition, je le trouve plus claire
d'écrire :
x = ( condition
? a
: b ) ;
J'aimerais savoir ce que tu penses de :
ifstream fichier (condition ? "input1.txt" : "input2.txt");
Je précise ma question : le fait de se passer d'une variable
"nom_de_fichier" (ce qui est rendu possible par le fait qu'on utilise
"?:" et pas "if") est-il (d'après toi) un élément de clarification ou
d'obfuscation ?
Les règles sont bien plus compliquées que ça. Ni l'une ni l'autre des
expressions n'est privilégées, et les compilateur essaie de trouver un
type commun. Mais on limite le champs de ses recherches, quand même. En
gros :
- D'abord, il y a certaines conversions « standard » qui sont faites
systèmatiquement sur les deux types -- du genre tableau en pointeur.
- Des conversions arithmétiques habituelles peuvent être appliquées
aux deux côtés, si nécessaire.
- Si une des expressions donne un pointeur, et l'autre est une
constante integrale de valeur 0, la constante integrale est
convertie en pointeur nul.
- Si les types des deux expressions sont tous les deux des pointeurs
ou des références à des classes, et une des classes est une classe
de base de l'autre, le pointeur au type dérivé est converti en
pointeur au type de base.
- Il y a le cas spécial où une des expressions est une expression de
throw (qui a le type void) -- le type final est le type de l'autre
expression (qui serait évidemment le seul qui pourrait servir comme
résultat).
Il y a d'autres cas aussi, mais je crois qu'ils servent moins souvent.
Il y a un cas dont l'absense me frustre de temps en temps : si les types
des deux expressions sont des pointeurs à des classes, et les deux
classes ont une classe de base en commun, ça ne marche pas. Donc, des
choses comme :
Base* pb = condition ? new Derived1 : new Derived2 ;
ne marche pas ; il faut explicitement convertir au moins un des
expressions en type Base*. L'une ou l'autre (ou les deux), ça ne fait
rien.Dans ton exemple, le résultat est "cout << 3" si vrai "cout << (int)
4.568"
si faux
Dans son exemple, le cout était en dehors de l'expression
conditionnelle. Et le type de l'expression conditionnelle, c'était bien
double, et non int, c-à-d que son expression totale était l'équivalent
de :
cout << (b1 ? static_cast< double >( 3 ) : 4.568) ;
(C'est le deuxième point cité ci-dessus : les conversions arithmétiques
habituelles.) Dans son premier exemple, il y avait aussi des
conversions, puisque le type de la première expression était char
const[7], et celui de la deuxième char const[11]. Ici, c'est le premier
point qui s'applique ; on verrait bien la différence en faisant :
sizeof( b2 ? "TROUVE" : "NON TROUVE" )
(qui ne vaut ni sizeof( "TROUVE" ) ni sizeof( "NON TROUVE" ), sauf cas
accidentel).
Les règles sont bien plus compliquées que ça. Ni l'une ni l'autre des
expressions n'est privilégées, et les compilateur essaie de trouver un
type commun. Mais on limite le champs de ses recherches, quand même. En
gros :
- D'abord, il y a certaines conversions « standard » qui sont faites
systèmatiquement sur les deux types -- du genre tableau en pointeur.
- Des conversions arithmétiques habituelles peuvent être appliquées
aux deux côtés, si nécessaire.
- Si une des expressions donne un pointeur, et l'autre est une
constante integrale de valeur 0, la constante integrale est
convertie en pointeur nul.
- Si les types des deux expressions sont tous les deux des pointeurs
ou des références à des classes, et une des classes est une classe
de base de l'autre, le pointeur au type dérivé est converti en
pointeur au type de base.
- Il y a le cas spécial où une des expressions est une expression de
throw (qui a le type void) -- le type final est le type de l'autre
expression (qui serait évidemment le seul qui pourrait servir comme
résultat).
Il y a d'autres cas aussi, mais je crois qu'ils servent moins souvent.
Il y a un cas dont l'absense me frustre de temps en temps : si les types
des deux expressions sont des pointeurs à des classes, et les deux
classes ont une classe de base en commun, ça ne marche pas. Donc, des
choses comme :
Base* pb = condition ? new Derived1 : new Derived2 ;
ne marche pas ; il faut explicitement convertir au moins un des
expressions en type Base*. L'une ou l'autre (ou les deux), ça ne fait
rien.
Dans ton exemple, le résultat est "cout << 3" si vrai "cout << (int)
4.568"
si faux
Dans son exemple, le cout était en dehors de l'expression
conditionnelle. Et le type de l'expression conditionnelle, c'était bien
double, et non int, c-à-d que son expression totale était l'équivalent
de :
cout << (b1 ? static_cast< double >( 3 ) : 4.568) ;
(C'est le deuxième point cité ci-dessus : les conversions arithmétiques
habituelles.) Dans son premier exemple, il y avait aussi des
conversions, puisque le type de la première expression était char
const[7], et celui de la deuxième char const[11]. Ici, c'est le premier
point qui s'applique ; on verrait bien la différence en faisant :
sizeof( b2 ? "TROUVE" : "NON TROUVE" )
(qui ne vaut ni sizeof( "TROUVE" ) ni sizeof( "NON TROUVE" ), sauf cas
accidentel).
Les règles sont bien plus compliquées que ça. Ni l'une ni l'autre des
expressions n'est privilégées, et les compilateur essaie de trouver un
type commun. Mais on limite le champs de ses recherches, quand même. En
gros :
- D'abord, il y a certaines conversions « standard » qui sont faites
systèmatiquement sur les deux types -- du genre tableau en pointeur.
- Des conversions arithmétiques habituelles peuvent être appliquées
aux deux côtés, si nécessaire.
- Si une des expressions donne un pointeur, et l'autre est une
constante integrale de valeur 0, la constante integrale est
convertie en pointeur nul.
- Si les types des deux expressions sont tous les deux des pointeurs
ou des références à des classes, et une des classes est une classe
de base de l'autre, le pointeur au type dérivé est converti en
pointeur au type de base.
- Il y a le cas spécial où une des expressions est une expression de
throw (qui a le type void) -- le type final est le type de l'autre
expression (qui serait évidemment le seul qui pourrait servir comme
résultat).
Il y a d'autres cas aussi, mais je crois qu'ils servent moins souvent.
Il y a un cas dont l'absense me frustre de temps en temps : si les types
des deux expressions sont des pointeurs à des classes, et les deux
classes ont une classe de base en commun, ça ne marche pas. Donc, des
choses comme :
Base* pb = condition ? new Derived1 : new Derived2 ;
ne marche pas ; il faut explicitement convertir au moins un des
expressions en type Base*. L'une ou l'autre (ou les deux), ça ne fait
rien.Dans ton exemple, le résultat est "cout << 3" si vrai "cout << (int)
4.568"
si faux
Dans son exemple, le cout était en dehors de l'expression
conditionnelle. Et le type de l'expression conditionnelle, c'était bien
double, et non int, c-à-d que son expression totale était l'équivalent
de :
cout << (b1 ? static_cast< double >( 3 ) : 4.568) ;
(C'est le deuxième point cité ci-dessus : les conversions arithmétiques
habituelles.) Dans son premier exemple, il y avait aussi des
conversions, puisque le type de la première expression était char
const[7], et celui de la deuxième char const[11]. Ici, c'est le premier
point qui s'applique ; on verrait bien la différence en faisant :
sizeof( b2 ? "TROUVE" : "NON TROUVE" )
(qui ne vaut ni sizeof( "TROUVE" ) ni sizeof( "NON TROUVE" ), sauf cas
accidentel).