une petite question rapide car je sais qu'il y a des gourous de la norme
ici ;)
j'ai une fonction qui attend un pointeur en paramètre. l'objet que je
veux passer est temporaire et ne sera pas utilisé par la suite ; afin de
ne pas rajouter trop de lignes à mon programme, j'aimerais le passer de
manière muette, sans le nommer.
--> ce qu'il faudrait faire :
A a(p1, p2, ...);
f(&a);
--> ce sur quoi j'ai un doute :
f(&::A(p1, p1, ...));
Visual me permet de faire ca, mais je ne suis pas convaincu que ce soit
correcte d'un point de vue norme. Qu'en pensez vous ?
Merci d'avance et a+
--
Yann Renard - To send me an email, remove no-spam sectionS :)
Merci pour cette réponse, qui confirme ce que je pensais ;)
Si tu n'as pas Comeau, tu peux tester du code ici : <http://www.comeaucomputing.com/tryitout/>.
Accessoirement, une version récente de g++, en mode le plus strict, devrait faire l'affaire.
Jean-Marc Bourguet
Fabien LE LEZ writes:
Soit le code ci-dessous :
struct A { A (int, int); };
void f (A*);
int main() { f (&A(1,2)); }
L'intuition fait tiquer, mais j'aurais pensé que ce code était correct. Ben non, Comeau râle :
error: expression must be an lvalue or a function designator f (&A(1,2)); ^
A noter que le code n'est pas non plus valide avec f(A const*) a la place de f(A*).
A comparer avec passer un temporaire a f(A const&) qui est permis tandis qu'a f(A&) ce ne l'est pas.
A+
-- Jean-Marc FAQ de fclc++: http://www.cmla.ens-cachan.fr/~dosreis/C++/FAQ C++ FAQ Lite en VF: http://www.ifrance.com/jlecomte/c++/c++-faq-lite/index.html Site de usenet-fr: http://www.usenet-fr.news.eu.org
Fabien LE LEZ <gramster@gramster.com> writes:
Soit le code ci-dessous :
struct A
{
A (int, int);
};
void f (A*);
int main()
{
f (&A(1,2));
}
L'intuition fait tiquer, mais j'aurais pensé que ce code était
correct. Ben non, Comeau râle :
error: expression must be an lvalue or a function designator
f (&A(1,2));
^
A noter que le code n'est pas non plus valide avec f(A const*) a la
place de f(A*).
A comparer avec passer un temporaire a f(A const&) qui est permis
tandis qu'a f(A&) ce ne l'est pas.
A+
--
Jean-Marc
FAQ de fclc++: http://www.cmla.ens-cachan.fr/~dosreis/C++/FAQ
C++ FAQ Lite en VF: http://www.ifrance.com/jlecomte/c++/c++-faq-lite/index.html
Site de usenet-fr: http://www.usenet-fr.news.eu.org
L'intuition fait tiquer, mais j'aurais pensé que ce code était correct. Ben non, Comeau râle :
error: expression must be an lvalue or a function designator f (&A(1,2)); ^
A noter que le code n'est pas non plus valide avec f(A const*) a la place de f(A*).
A comparer avec passer un temporaire a f(A const&) qui est permis tandis qu'a f(A&) ce ne l'est pas.
A+
-- Jean-Marc FAQ de fclc++: http://www.cmla.ens-cachan.fr/~dosreis/C++/FAQ C++ FAQ Lite en VF: http://www.ifrance.com/jlecomte/c++/c++-faq-lite/index.html Site de usenet-fr: http://www.usenet-fr.news.eu.org
Yann Renard
Fabien LE LEZ wrote:
On Mon, 19 Dec 2005 15:17:54 +0100, Yann Renard :
Merci pour cette réponse, qui confirme ce que je pensais ;)
Si tu n'as pas Comeau, tu peux tester du code ici : <http://www.comeaucomputing.com/tryitout/>.
Accessoirement, une version récente de g++, en mode le plus strict, devrait faire l'affaire.
Superbe, merci beaucoup !
Yann -- Yann Renard - To send me an email, remove no-spam sectionS :)
Fabien LE LEZ wrote:
On Mon, 19 Dec 2005 15:17:54 +0100, Yann Renard :
Merci pour cette réponse, qui confirme ce que je pensais ;)
Si tu n'as pas Comeau, tu peux tester du code ici :
<http://www.comeaucomputing.com/tryitout/>.
Accessoirement, une version récente de g++, en mode le plus strict,
devrait faire l'affaire.
Superbe, merci beaucoup !
Yann
--
Yann Renard - To send me an email, remove no-spam sectionS :)
Mais il ment pas mal -- scoped_ptr signifie une propriété partagée, qui n'est pas le cas ici.
Si tu veux rester standard, tu peux faire exactement la même chose avec auto_ptr. Si tu utilises des extensions, un simple new suffit, et le glaneur de cellules s'occupe de la reste. (Et comme extension, le glaneur de cellules est à la fois plus simple à installer et à utiliser, et plus utile que Boost. Ce qui n'est pas peu dire, parce qu'il y a des choses vraiment utiles dans Boost.)
Ça ne simplifie pas vraiment l'écriture, mais si tu as besoin de passer un objet non nommé, ça fonctionne.
Non seulement c'est lourd à l'écriture, mais ça utilise de la mémoire dynamique, ce qui peut aussi représenter une lourdeur.
La règle de la norme est simple : l'opérateur unaire & a besoin d'un « lvalue ». Ici, formellement, on a un « function style cast », bien que moi, j'ai du mal à concevoir A( p1, p2, ... ) comme une conversion). Un « function style cast » n'est pas un lvalue. C'est donc illégal.
AMHA, la solution la plus claire et la plus lisible reste la variable explicite. N'importe qui qui connaît un peu du C++ sait immédiatement exactement ce que ça fait. Sinon... il s'agit d'un type « classe ». Donc, même un lvalue est un objet. Et un objet a certains caractèristiques d'un lvalue, même quand il n'en est pas un : surtout, il a une adresse, et on peut en appeler des fonctions membres. On en peut aussi surcharger l'opérateur &, et alors, l'application de & est un appel de fonction membre, ce qui peut se faire sur un rvalue. Si tu as accès à A, tu peux lui en fournir un surcharge :
A* A::operator&() { return this ; } A const* A::operator&() const { return this ; }
Sinon, tu peux en dériver, et fournir l'opérateur ci-dessus dans la classe dérivée.
Mais comme j'ai dit, AMHA, ça relève de l'obfuscation plus que de la bonne programmation. Déjà une fonction avec un nom bien parlant signalera mieux au lecteur qu'il se passe quelque chose de spécial. Mais je crois qu'en général, la variable nommée est la plus claire et la plus explicite.
-- James Kanze GABI Software 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
Pierre THIERRY wrote:
--> ce qu'il faudrait faire :
A a(p1, p2, ...);
f(&a);
--> ce sur quoi j'ai un doute :
f(&::A(p1, p1, ...));
Mais il ment pas mal -- scoped_ptr signifie une propriété partagée,
qui
n'est pas le cas ici.
Si tu veux rester standard, tu peux faire exactement la même chose
avec
auto_ptr. Si tu utilises des extensions, un simple new suffit, et le
glaneur de cellules s'occupe de la reste. (Et comme extension, le
glaneur de cellules est à la fois plus simple à installer et à
utiliser,
et plus utile que Boost. Ce qui n'est pas peu dire, parce qu'il y a des
choses vraiment utiles dans Boost.)
Ça ne simplifie pas vraiment l'écriture, mais si tu as besoin de
passer un objet non nommé, ça fonctionne.
Non seulement c'est lourd à l'écriture, mais ça utilise de la
mémoire
dynamique, ce qui peut aussi représenter une lourdeur.
La règle de la norme est simple : l'opérateur unaire & a besoin d'un
« lvalue ». Ici, formellement, on a un « function style cast »,
bien que
moi, j'ai du mal à concevoir A( p1, p2, ... ) comme une conversion).
Un
« function style cast » n'est pas un lvalue. C'est donc illégal.
AMHA, la solution la plus claire et la plus lisible reste la variable
explicite. N'importe qui qui connaît un peu du C++ sait immédiatement
exactement ce que ça fait. Sinon... il s'agit d'un type « classe ».
Donc, même un lvalue est un objet. Et un objet a certains
caractèristiques d'un lvalue, même quand il n'en est pas un :
surtout,
il a une adresse, et on peut en appeler des fonctions membres. On en
peut aussi surcharger l'opérateur &, et alors, l'application de & est
un
appel de fonction membre, ce qui peut se faire sur un rvalue. Si tu as
accès à A, tu peux lui en fournir un surcharge :
A* A::operator&() { return this ; }
A const* A::operator&() const { return this ; }
Sinon, tu peux en dériver, et fournir l'opérateur ci-dessus dans la
classe dérivée.
Mais comme j'ai dit, AMHA, ça relève de l'obfuscation plus que de la
bonne programmation. Déjà une fonction avec un nom bien parlant
signalera mieux au lecteur qu'il se passe quelque chose de spécial.
Mais
je crois qu'en général, la variable nommée est la plus claire et la
plus explicite.
--
James Kanze GABI Software
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
Mais il ment pas mal -- scoped_ptr signifie une propriété partagée, qui n'est pas le cas ici.
Si tu veux rester standard, tu peux faire exactement la même chose avec auto_ptr. Si tu utilises des extensions, un simple new suffit, et le glaneur de cellules s'occupe de la reste. (Et comme extension, le glaneur de cellules est à la fois plus simple à installer et à utiliser, et plus utile que Boost. Ce qui n'est pas peu dire, parce qu'il y a des choses vraiment utiles dans Boost.)
Ça ne simplifie pas vraiment l'écriture, mais si tu as besoin de passer un objet non nommé, ça fonctionne.
Non seulement c'est lourd à l'écriture, mais ça utilise de la mémoire dynamique, ce qui peut aussi représenter une lourdeur.
La règle de la norme est simple : l'opérateur unaire & a besoin d'un « lvalue ». Ici, formellement, on a un « function style cast », bien que moi, j'ai du mal à concevoir A( p1, p2, ... ) comme une conversion). Un « function style cast » n'est pas un lvalue. C'est donc illégal.
AMHA, la solution la plus claire et la plus lisible reste la variable explicite. N'importe qui qui connaît un peu du C++ sait immédiatement exactement ce que ça fait. Sinon... il s'agit d'un type « classe ». Donc, même un lvalue est un objet. Et un objet a certains caractèristiques d'un lvalue, même quand il n'en est pas un : surtout, il a une adresse, et on peut en appeler des fonctions membres. On en peut aussi surcharger l'opérateur &, et alors, l'application de & est un appel de fonction membre, ce qui peut se faire sur un rvalue. Si tu as accès à A, tu peux lui en fournir un surcharge :
A* A::operator&() { return this ; } A const* A::operator&() const { return this ; }
Sinon, tu peux en dériver, et fournir l'opérateur ci-dessus dans la classe dérivée.
Mais comme j'ai dit, AMHA, ça relève de l'obfuscation plus que de la bonne programmation. Déjà une fonction avec un nom bien parlant signalera mieux au lecteur qu'il se passe quelque chose de spécial. Mais je crois qu'en général, la variable nommée est la plus claire et la plus explicite.
-- James Kanze GABI Software 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