Quand je compile le code suivant à l'aide g++
Opérateurs de conversion de type référence: demander des problèmes?
class A {};
void foo(A&) {}
int main()
{
foo(A());
return 0;
}
Je reçois des messages d'erreur suivants:
> g++ test.cpp -o test
test.cpp: In function ‘int main()’:
test.cpp:10: error: invalid initialization of non-const reference of type ‘A&’ from a temporary of type ‘A’
test.cpp:6: error: in passing argument 1 of ‘void foo(A&)’
Après réflexion, ces erreurs font beaucoup de sens pour moi. A()
est juste une valeur temporaire, pas un emplacement assignable sur la pile, donc il ne semble pas avoir d'adresse. Si elle n'a pas d'adresse, je ne peux pas y faire référence. D'accord, d'accord.
Mais attendez! Si j'ajoute l'opérateur de conversion suivant à la classe A
class A
{
public:
operator A&() { return *this; }
};
tout va bien! Ma question est de savoir si cela est même à distance. Qu'est-ce que this
fait exactement quand A()
est construit comme une valeur temporaire?
Je me donne une certaine confiance par le fait que
void foo(const A&) {}
peut accepter des valeurs temporaires selon g++
et tous les autres compilateurs que j'ai utilisé. Le mot-clé const
peut toujours être supprimé, donc il me surprendrait s'il y avait des différences sémantiques réelles entre un paramètre const A&
et un paramètre A&
. Donc, je suppose que c'est une autre façon de poser ma question: pourquoi une référence const
à une valeur temporaire considérée comme sûre par le compilateur alors qu'une référence non const
ne l'est pas?
Je suis d'accord que ce genre de chose est généralement une erreur de programmeur. Dans le cas où vous êtes curieux, la classe que j'essaie de transmettre en tant que référence est une sorte de pointeur intelligent, qui a un membre de pointeur sous-jacent alloué. Je veux réellement que la fonction de réception fasse des choses avec le pointeur sous-jacent. Je veux juste m'assurer que le pointeur intelligent temporaire n'est pas détruit (en décrémentant le nombre de références) jusqu'à ce que la fonction de réception revienne. – Ben
Si c'est votre intention, déclarez le pointeur intelligent sur la pile explicitement et transmettez-le ou transmettez-le par valeur. Si vous le transmettez par valeur, vous avez la certitude qu'il ne sera pas détruit avant la fin de la fonction. – MSN
@Ben - ajouté quelques-uns à mon post à ce sujet. Je ne peux pas dire si c'est une bonne idée pour vous sans voir votre code, mais il y a quelques cas d'utilisation (et il ne sera pas détruit jusqu'à ce qu'il revienne) –