Pour autant que je sache, il n'y a aucune raison pour laquelle je ne devrais pas être autorisé à passer une référence à un pointeur en C ++. Cependant, mes tentatives pour le faire échouent, et je n'ai aucune idée pourquoi.
Voici ce que je fais:
void myfunc(string*& val)
{
// Do stuff to the string pointer
}
// sometime later
{
// ...
string s;
myfunc(&s);
// ...
}
Et j'obtiens cette erreur:
impossible de convertir le paramètre 1 de 'std :: string *' en 'std :: string * &'
string* const& val
au lieu d'un équivalent moins lisible comme par exempleconst string* &val
. À mes yeux, c'est clairement une référence const , à un pointeur, à une chaîne. Personnellement, je préfère écrireT const&
plutôt queconst T&
dans les déclarations pour obtenir cette précision exacte.bind a temporary to the reference
est plus claire dans cette réponse que @Chris 'asreference to an actual string pointer in the calling scope, not an anonymous string pointer
. Quoi qu'il en soit, les deux sont probablement corrects de mon point de vue.const string*&
etstring* const&
sont en fait des types différents. Le premier est une non-const
référence à aconst string*
, tandis que le second est uneconst
référence à astring*
.T const&
àconst T&
- comme le souligne @Justin Time, ce sont des types différents. Il peut avoir aucune conséquence parfois, mais dans d' autres situations , il sera absolument essentiel de préférer un ou l' autre, un peu comme préférantint
àdouble
.Changez-le en:
ÉDITER:
Ceci est appelé
ref-to-pointer
et vous ne pouvez pas passer d'adresse temporaire comme référence à la fonction. (sauf si c'est le casconst reference
).Cependant, j'ai montré
std::string* pS = &s;
(pointeur vers une variable locale), son utilisation typique serait: lorsque vous voulez que l'appelé change le pointeur lui-même, pas l'objet vers lequel il pointe. Par exemple, une fonction qui alloue de la mémoire et attribue l'adresse du bloc de mémoire qu'elle a alloué à son argument doit prendre une référence à un pointeur, ou un pointeur à un pointeur:la source
&s
produit un pointeur temporaire vers une chaîne et vous ne pouvez pas faire référence à un objet temporaire.la source
Essayer:
ou
la source
EDIT: J'en ai expérimenté, et j'ai découvert que les choses sont un peu plus subtiles que je ne le pensais. Voici ce que je pense maintenant être une réponse exacte.
&s
n'est pas une lvalue, vous ne pouvez donc pas y créer de référence à moins que le type de la référence ne fasse référence àconst
. Donc, par exemple, vous ne pouvez pas fairemais tu peux faire
Si vous mettez une déclaration similaire dans l'en-tête de la fonction, cela fonctionnera.
Il y a un autre problème, celui des temporaires. La règle est que vous ne pouvez obtenir une référence à un temporaire que si c'est le cas
const
. Donc, dans ce cas, on pourrait affirmer que & s est temporaire et doit donc être déclaréconst
dans le prototype de fonction. D'un point de vue pratique, cela ne fait aucune différence dans ce cas. (C'est soit une valeur, soit une valeur temporaire. De toute façon, la même règle s'applique.) Cependant, à proprement parler, je pense que ce n'est pas une valeur temporaire mais une valeur. Je me demande s'il existe un moyen de faire la distinction entre les deux. (Peut-être est-il simplement défini que toutes les valeurs temporaires sont des valeurs, et toutes les valeurs non-l sont des valeurs temporaires. Je ne suis pas un expert de la norme.)Cela étant dit, votre problème se situe probablement à un niveau supérieur. Pourquoi voulez-vous une référence à l'adresse de
s
? Si vous voulez une référence à un pointeur verss
, vous devez définir un pointeur comme dansSi vous voulez une référence
s
ou un pointeur verss
, faites la chose simple.la source
Je viens de faire usage d'une référence à un pointeur pour rendre tous les pointeurs dans un arbre binaire supprimé sauf la racine en toute sécurité. Pour rendre le pointeur sûr, nous devons juste le mettre à 0. Je ne pouvais pas faire en sorte que la fonction qui supprime l'arbre (en ne gardant que la racine) accepte une référence vers un pointeur puisque j'utilise la racine (ce pointeur) comme premier entrée pour parcourir à gauche et à droite.
En bout de ligne, une référence à un pointeur n'est pas valide lorsque le paramètre formel est le pointeur (this).
la source
Bienvenue dans les références C ++ 11 et rvalue:
Vous avez maintenant accès à la valeur du pointeur (référencé par
val
), qui est l'adresse de la chaîne.Vous pouvez modifier le pointeur, et personne ne s'en souciera. C'est un aspect de ce qu'est une rvalue en premier lieu.
Attention: la valeur du pointeur n'est valide que jusqu'au
myfunc()
retour. Enfin, c'est temporaire.la source
Je sais qu'il est possible de passer des références de pointeurs, je l'ai fait la semaine dernière, mais je ne me souviens pas quelle était la syntaxe, car votre code semble correct pour mon cerveau en ce moment. Cependant, une autre option consiste à utiliser des pointeurs de pointeurs:
la source
myfunc ("string * & val") cela n'a aucun sens en soi. "string * & val" implique "string val", * et & s'annule. Enfin on ne peut pas passer de variable string à une fonction ("string val"). Seuls les types de données de base peuvent être passés à une fonction, car les autres types de données doivent passer en tant que pointeur ou référence. Vous pouvez ajouter une chaîne & val ou une chaîne * val à une fonction.
la source