>C'est peut-être un peu strict comme réponse. On peut créer >une classe propriété (qui contient un int), définir un >operateur | sur les objets de cette classe, contrôler les >constructeurs pour que toute propriété soit soit une des 4 de >base soit une copie soit le résultat de |.
En gros, tu proposes une solution compliquée pour faire fonctionner un abus, alors qu'il existe une solution simple et légitime au problème.
Sauf que la solution est plus simple que celle que tu proposes. L'opérateur|, par exemple, s'implémente avec quelque cast ; avec ta solution, il faudrait traiter chaque champ explicitement.
-- 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
On Mar 30, 10:21 pm, Fabien LE LEZ <grams...@gramster.com> wrote:
On Mon, 30 Mar 2009 19:39:15 +0000 (UTC), Marc
<marc.gli...@gmail.com>:
>C'est peut-être un peu strict comme réponse. On peut créer
>une classe propriété (qui contient un int), définir un
>operateur | sur les objets de cette classe, contrôler les
>constructeurs pour que toute propriété soit soit une des 4 de
>base soit une copie soit le résultat de |.
En gros, tu proposes une solution compliquée pour faire
fonctionner un abus, alors qu'il existe une solution simple et
légitime au problème.
Sauf que la solution est plus simple que celle que tu proposes.
L'opérateur|, par exemple, s'implémente avec quelque cast ;
avec ta solution, il faudrait traiter chaque champ
explicitement.
--
James Kanze (GABI Software) email:james.kanze@gmail.com
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
>C'est peut-être un peu strict comme réponse. On peut créer >une classe propriété (qui contient un int), définir un >operateur | sur les objets de cette classe, contrôler les >constructeurs pour que toute propriété soit soit une des 4 de >base soit une copie soit le résultat de |.
En gros, tu proposes une solution compliquée pour faire fonctionner un abus, alors qu'il existe une solution simple et légitime au problème.
Sauf que la solution est plus simple que celle que tu proposes. L'opérateur|, par exemple, s'implémente avec quelque cast ; avec ta solution, il faudrait traiter chaque champ explicitement.
-- 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
inline Properties operator|(Properties a, Properties b) { // Note: Unary '+' forces integral promotion return static_cast<Properties>(+a | +b); }
Ca ne serait pas plus explicite d'utiliser static_cast<int> pour la conversion en entier ? J'avoue que sans le commentaire, je n'aurais pas compris tout de suite...
Je trouve que la solution avec le static_cast<int> a deux défauts : un mineur (ça fait plus de texte à taper :-)) et un majeur au niveau de la maintenance - le jour où quelqu'un ajoute un 'PROPERTY42 = 1ULL << 42' dans l'enum, int ne convient plus et on risque d'oublier de mettre à jour le cast, tandis qu'avec le +, le compilateur se débrouille tout seul pour trouver le type intégral qui convient (chaque type énuméré possède un type intégral sous-jacent, suffisamment grand pour représenter les valeurs énumérées).
Pour le mineur, pas de commentaire, c'est une histoire de gout.
Pour le majeur, c'est plus serieux. James mentionne dans un autre post la possibilite de determiner le type entier sous-jacent avec des templates (et je viens de decouvrir boost::integral_promotion), mais c'est interessant de savoir qu'un simple '+' evite de sortir l'artillerie lourde.
inline Properties operator|(Properties a, Properties b)
{ // Note: Unary '+' forces integral promotion
return static_cast<Properties>(+a | +b);
}
Ca ne serait pas plus explicite d'utiliser static_cast<int> pour
la conversion en entier ? J'avoue que sans le commentaire, je
n'aurais pas compris tout de suite...
Je trouve que la solution avec le static_cast<int> a deux défauts : un
mineur (ça fait plus de texte à taper :-)) et un majeur au niveau de la
maintenance - le jour où quelqu'un ajoute un 'PROPERTY42 = 1ULL << 42'
dans l'enum, int ne convient plus et on risque d'oublier de mettre à
jour le cast, tandis qu'avec le +, le compilateur se débrouille tout
seul pour trouver le type intégral qui convient (chaque type énuméré
possède un type intégral sous-jacent, suffisamment grand pour
représenter les valeurs énumérées).
Pour le mineur, pas de commentaire, c'est une histoire de gout.
Pour le majeur, c'est plus serieux. James mentionne dans un autre
post la possibilite de determiner le type entier sous-jacent avec
des templates (et je viens de decouvrir boost::integral_promotion),
mais c'est interessant de savoir qu'un simple '+' evite de sortir
l'artillerie lourde.
inline Properties operator|(Properties a, Properties b) { // Note: Unary '+' forces integral promotion return static_cast<Properties>(+a | +b); }
Ca ne serait pas plus explicite d'utiliser static_cast<int> pour la conversion en entier ? J'avoue que sans le commentaire, je n'aurais pas compris tout de suite...
Je trouve que la solution avec le static_cast<int> a deux défauts : un mineur (ça fait plus de texte à taper :-)) et un majeur au niveau de la maintenance - le jour où quelqu'un ajoute un 'PROPERTY42 = 1ULL << 42' dans l'enum, int ne convient plus et on risque d'oublier de mettre à jour le cast, tandis qu'avec le +, le compilateur se débrouille tout seul pour trouver le type intégral qui convient (chaque type énuméré possède un type intégral sous-jacent, suffisamment grand pour représenter les valeurs énumérées).
Pour le mineur, pas de commentaire, c'est une histoire de gout.
Pour le majeur, c'est plus serieux. James mentionne dans un autre post la possibilite de determiner le type entier sous-jacent avec des templates (et je viens de decouvrir boost::integral_promotion), mais c'est interessant de savoir qu'un simple '+' evite de sortir l'artillerie lourde.
James Kanze
On Mar 30, 10:09 pm, Falk Tannhäuser wrote:
Guillaume GOURDIN schrieb:
[...]
inline Properties operator|(Properties a, Properties b) { // Note: Unary '+' forces integral promotion return static_cast<Properties>(+a | +b);
Et est assez subtile qu'il faut un commentaire. Et donc, plus de text qu'une conversion explicite.
En revanche, il évite le problème de nommer le type soujacent. Qui dépend des valeurs dans l'enum et les tailles des types entiers sur la machine en question. Je crois que je vais l'adopter:-).
-- 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
On Mar 30, 10:09 pm, Falk Tannhäuser <tannhauser86549s...@free.fr>
wrote:
Guillaume GOURDIN schrieb:
[...]
inline Properties operator|(Properties a, Properties b)
{ // Note: Unary '+' forces integral promotion
return static_cast<Properties>(+a | +b);
Et est assez subtile qu'il faut un commentaire. Et donc, plus de
text qu'une conversion explicite.
En revanche, il évite le problème de nommer le type soujacent.
Qui dépend des valeurs dans l'enum et les tailles des types
entiers sur la machine en question. Je crois que je vais
l'adopter:-).
--
James Kanze (GABI Software) email:james.kanze@gmail.com
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
inline Properties operator|(Properties a, Properties b) { // Note: Unary '+' forces integral promotion return static_cast<Properties>(+a | +b);
Et est assez subtile qu'il faut un commentaire. Et donc, plus de text qu'une conversion explicite.
En revanche, il évite le problème de nommer le type soujacent. Qui dépend des valeurs dans l'enum et les tailles des types entiers sur la machine en question. Je crois que je vais l'adopter:-).
-- 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
inline Properties operator|(Properties a, Properties b) { // Note: Unary '+' forces integral promotion return static_cast<Properties>(+a | +b); }
Ca ne serait pas plus explicite d'utiliser static_cast<int> pour la conversion en entier ?
Et si on ajoute un « propertyx = 1ULL << 48 » ?
On doit corriger controler et eventuellement corriger tous les operateurs redefinis. Effectivement, on voudrait s'en passer.
Michel Decima
James Kanze a écrit :
On Mar 30, 10:09 pm, Falk Tannhäuser wrote:
Guillaume GOURDIN schrieb:
[...]
inline Properties operator|(Properties a, Properties b) { // Note: Unary '+' forces integral promotion return static_cast<Properties>(+a | +b);
Et est assez subtile qu'il faut un commentaire. Et donc, plus de text qu'une conversion explicite.
En revanche, il évite le problème de nommer le type soujacent. Qui dépend des valeurs dans l'enum et les tailles des types entiers sur la machine en question. Je crois que je vais l'adopter:-).
Si on voulait nommer le type sous-jacent, pour une variable temporaire par exemple, il faudrait sortir la solution a base de template que tu as proposee, donc quelque chose comme ceci :
Properties a = ... ; boost::integral_promotion<Properties> i = a ;
au moins, c'est lisible. Mais si on combine l'astuce du '+' avec le decltype de c++0x, on pourrait faire :
decltype( +a ) i = a ;
qui est tres sympathique pour ceux qui vont relire le code plus tard ;)
James Kanze a écrit :
On Mar 30, 10:09 pm, Falk Tannhäuser <tannhauser86549s...@free.fr>
wrote:
Guillaume GOURDIN schrieb:
[...]
inline Properties operator|(Properties a, Properties b)
{ // Note: Unary '+' forces integral promotion
return static_cast<Properties>(+a | +b);
Et est assez subtile qu'il faut un commentaire. Et donc, plus de
text qu'une conversion explicite.
En revanche, il évite le problème de nommer le type soujacent.
Qui dépend des valeurs dans l'enum et les tailles des types
entiers sur la machine en question. Je crois que je vais
l'adopter:-).
Si on voulait nommer le type sous-jacent, pour une variable
temporaire par exemple, il faudrait sortir la solution a
base de template que tu as proposee, donc quelque chose
comme ceci :
Properties a = ... ;
boost::integral_promotion<Properties> i = a ;
au moins, c'est lisible. Mais si on combine l'astuce
du '+' avec le decltype de c++0x, on pourrait faire :
decltype( +a ) i = a ;
qui est tres sympathique pour ceux qui vont relire
le code plus tard ;)
inline Properties operator|(Properties a, Properties b) { // Note: Unary '+' forces integral promotion return static_cast<Properties>(+a | +b);
Et est assez subtile qu'il faut un commentaire. Et donc, plus de text qu'une conversion explicite.
En revanche, il évite le problème de nommer le type soujacent. Qui dépend des valeurs dans l'enum et les tailles des types entiers sur la machine en question. Je crois que je vais l'adopter:-).
Si on voulait nommer le type sous-jacent, pour une variable temporaire par exemple, il faudrait sortir la solution a base de template que tu as proposee, donc quelque chose comme ceci :
Properties a = ... ; boost::integral_promotion<Properties> i = a ;
au moins, c'est lisible. Mais si on combine l'astuce du '+' avec le decltype de c++0x, on pourrait faire :
decltype( +a ) i = a ;
qui est tres sympathique pour ceux qui vont relire le code plus tard ;)
Ca ne serait pas plus explicite d'utiliser static_cast<int> pour la conversion en entier ?
Et si on ajoute un « propertyx = 1ULL << 48 » ?
On doit corriger controler et eventuellement corriger tous les operateurs redefinis. Effectivement, on voudrait s'en passer.
Franchement, est ce vraiment utile? Je ne vois pas l'intérêt d'atteindre un tel niveau de fort typage, vu l'ampleur du travail que ça demande. Ne peut on se contenter d'un test:
Avec ce prototype de fonction, l'argument props est un int, qui est (souvent) trop petit pour contenir le PROPERTY48 suggere par James, donc il faut revoir le prototype si on ajoute une telle valeur. Si l'argument etait un Properties, on n'aurait pas eu le probleme.
On peut se contenter d'un typedef, mais ca laisse la possibilite de faire n'importe quoi (genre +, -), et on ne peut plus surcharger l'operateur d'affichage.
Apres, est-ce que ca vaut la peine, c'est une autre histoire.
Pascal J. Bourguignon a écrit :
Michel Decima <michel.decima@orange-ft.com> writes:
James Kanze a écrit :
On Mar 31, 10:03 am, Michel Decima <michel.dec...@orange-ft.com>
wrote:
Ca ne serait pas plus explicite d'utiliser static_cast<int>
pour la conversion en entier ?
Et si on ajoute un « propertyx = 1ULL << 48 » ?
On doit corriger controler et eventuellement corriger tous
les operateurs redefinis. Effectivement, on voudrait s'en passer.
Franchement, est ce vraiment utile? Je ne vois pas l'intérêt
d'atteindre un tel niveau de fort typage, vu l'ampleur du travail que
ça demande.
Ne peut on se contenter d'un test:
Avec ce prototype de fonction, l'argument props est un int, qui est
(souvent) trop petit pour contenir le PROPERTY48 suggere par James,
donc il faut revoir le prototype si on ajoute une telle valeur.
Si l'argument etait un Properties, on n'aurait pas eu le probleme.
On peut se contenter d'un typedef, mais ca laisse la possibilite
de faire n'importe quoi (genre +, -), et on ne peut plus surcharger
l'operateur d'affichage.
Apres, est-ce que ca vaut la peine, c'est une autre histoire.
Ca ne serait pas plus explicite d'utiliser static_cast<int> pour la conversion en entier ?
Et si on ajoute un « propertyx = 1ULL << 48 » ?
On doit corriger controler et eventuellement corriger tous les operateurs redefinis. Effectivement, on voudrait s'en passer.
Franchement, est ce vraiment utile? Je ne vois pas l'intérêt d'atteindre un tel niveau de fort typage, vu l'ampleur du travail que ça demande. Ne peut on se contenter d'un test:
Avec ce prototype de fonction, l'argument props est un int, qui est (souvent) trop petit pour contenir le PROPERTY48 suggere par James, donc il faut revoir le prototype si on ajoute une telle valeur. Si l'argument etait un Properties, on n'aurait pas eu le probleme.
On peut se contenter d'un typedef, mais ca laisse la possibilite de faire n'importe quoi (genre +, -), et on ne peut plus surcharger l'operateur d'affichage.
Apres, est-ce que ca vaut la peine, c'est une autre histoire.