Soweit ich das beurteilen kann, gibt es keinen Grund, warum ich keinen Verweis auf einen Zeiger in C ++ übergeben darf. Meine Versuche scheitern jedoch, und ich habe keine Ahnung warum.
Das mache ich:
void myfunc(string*& val)
{
// Do stuff to the string pointer
}
// sometime later
{
// ...
string s;
myfunc(&s);
// ...
}
Und ich bekomme diesen Fehler:
Parameter 1 kann nicht von 'std :: string *' in 'std :: string * &' konvertiert werden.
string* const& val
anstelle eines weniger lesbaren Äquivalents wie zconst string* &val
. Für meine Augen ist dies eindeutig eine konstante Referenz , auf einen Zeiger, auf eine Zeichenfolge. Ich persönlich schreibeT const&
lieber alsconst T&
in Erklärungen, um genau diese Klarstellung zu erhalten.bind a temporary to the reference
in dieser Antwort klarer als bei @Chris 'asreference to an actual string pointer in the calling scope, not an anonymous string pointer
. Unabhängig davon sind beide aus meiner Sicht wahrscheinlich richtig.const string*&
undstring* const&
sind eigentlich verschiedene Typen. Die erste ist eine Nichtreferenzconst
auf aconst string*
, während die zweite eineconst
Referenz auf a iststring*
.T const&
zuconst T&
- wie @Justin Zeit weist darauf hin, sie unterschiedliche Typen sind. Es kann keine Folgen haben manchmal, aber in anderen Situationen wird es absolut entscheidend sein , einen oder anderen zu bevorzugen, ähnlich wie lieberint
zudouble
.Ändern Sie es in:
BEARBEITEN:
Dies wird aufgerufen
ref-to-pointer
und Sie können keine temporäre Adresse als Referenz auf die Funktion übergeben. (es sei denn, es istconst reference
).Obwohl ich gezeigt habe
std::string* pS = &s;
(Zeiger auf eine lokale Variable), wäre seine typische Verwendung: Wenn Sie möchten, dass der Angerufene den Zeiger selbst ändert, nicht das Objekt, auf das er zeigt. Beispielsweise muss eine Funktion, die Speicher zuweist und die Adresse des Speicherblocks zuweist, den sie ihrem Argument zugewiesen hat, einen Verweis auf einen Zeiger oder einen Zeiger auf einen Zeiger enthalten:quelle
&s
Erzeugt einen temporären Zeiger auf eine Zeichenfolge und Sie können nicht auf ein temporäres Objekt verweisen.quelle
Versuchen:
oder
quelle
EDIT: Ich habe einige experimentiert und festgestellt, dass die Dinge etwas subtiler sind, als ich dachte. Ich denke jetzt, dass dies eine genaue Antwort ist.
&s
ist kein l-Wert, daher können Sie keinen Verweis darauf erstellen, es sei denn, der Typ des Verweises ist ein Verweis daraufconst
. So können Sie zum Beispiel nicht tunaber du kannst es tun
Wenn Sie eine ähnliche Deklaration in den Funktionsheader einfügen, funktioniert dies.
Es gibt noch ein anderes Problem, nämlich Provisorien. Die Regel ist, dass Sie nur dann einen Verweis auf eine temporäre Datei erhalten können, wenn dies der Fall ist
const
. In diesem Fall könnte man also argumentieren, dass & s vorübergehend ist und daher deklariert werden mussconst
im Funktionsprototyp . Aus praktischer Sicht macht es in diesem Fall keinen Unterschied. (Es ist entweder ein r-Wert oder ein temporärer Wert. In beiden Fällen gilt die gleiche Regel.) Genau genommen denke ich jedoch, dass es kein temporärer, sondern ein r-Wert ist. Ich frage mich, ob es einen Weg gibt, zwischen den beiden zu unterscheiden. (Vielleicht wird einfach definiert, dass alle Provisorien r-Werte sind und alle Nicht-l-Werte temporäre Werte. Ich bin kein Experte für den Standard.)Davon abgesehen liegt Ihr Problem wahrscheinlich auf einem höheren Niveau. Warum möchten Sie einen Verweis auf die Adresse von
s
? Wenn Sie einen Verweis auf einen Zeiger auf möchtens
, müssen Sie einen Zeiger wie in definierenWenn Sie einen Verweis auf
s
oder einen Zeiger auf möchtens
, gehen Sie einfach vor.quelle
Ich habe gerade einen Verweis auf einen Zeiger verwendet, um alle Zeiger in einem gelöschten Binärbaum außer dem Stamm sicher zu machen. Um den Zeiger sicher zu machen, müssen wir ihn nur auf 0 setzen. Ich konnte die Funktion, die den Baum löscht (nur die Wurzel behalten), nicht dazu bringen, einen Verweis auf einen Zeiger zu akzeptieren, da ich die Wurzel (diesen Zeiger) als erste verwende Eingabe, um links und rechts zu durchlaufen.
Unterm Strich ist ein Verweis auf einen Zeiger ungültig, wenn der formale Parameter der (dieser) Zeiger ist.
quelle
Willkommen bei C ++ 11 und rvalue Referenzen:
Jetzt haben Sie Zugriff auf den Wert des Zeigers (auf den verwiesen wird
val
), der die Adresse der Zeichenfolge ist.Sie können den Zeiger ändern, und es interessiert niemanden. Das ist ein Aspekt dessen, was ein Wert überhaupt ist.
Achtung: Der Wert des Zeigers ist nur bis zur
myfunc()
Rückkehr gültig . Endlich ist es eine vorübergehende.quelle
Ich weiß, dass es möglich ist, Verweise auf Zeiger zu übergeben, ich habe es letzte Woche getan, aber ich kann mich nicht erinnern, wie die Syntax lautete, da Ihr Code für mein Gehirn im Moment korrekt aussieht. Eine andere Option ist jedoch die Verwendung von Zeigern von Zeigern:
quelle
myfunc ("string * & val") das selbst macht keinen Sinn. "string * & val" impliziert "string val", * und & heben sich gegenseitig auf. Schließlich kann man keine Stringvariable an eine Funktion übergeben ("string val"). Es können nur grundlegende Datentypen an eine Funktion übergeben werden, da andere Datentypen als Zeiger oder Referenz übergeben werden müssen. Sie können entweder string & val oder string * val für eine Funktion haben.
quelle