O ile wiem, nie ma powodu, dla którego nie powinienem mieć możliwości przekazywania referencji do wskaźnika w C ++. Jednak moje próby kończą się niepowodzeniem i nie mam pojęcia, dlaczego.
Oto co robię:
void myfunc(string*& val)
{
// Do stuff to the string pointer
}
// sometime later
{
// ...
string s;
myfunc(&s);
// ...
}
Otrzymuję ten błąd:
nie można przekonwertować parametru 1 z „std :: string *” na „std :: string * &”
string* const& val
zamiast mniej czytelnego odpowiednika, jak npconst string* &val
. Dla moich oczu jest to wyraźnie odniesienie do stałej , do wskaźnika, do struny. Osobiście wolę pisaćT const&
zamiastconst T&
deklaracji, aby uzyskać to dokładne wyjaśnienie.bind a temporary to the reference
jest jaśniejsza w tej odpowiedzi niż @Chris 'asreference to an actual string pointer in the calling scope, not an anonymous string pointer
. Niezależnie od tego, z mojej perspektywy oba są prawdopodobnie poprawne.const string*&
astring* const&
właściwie są to różne typy. Pierwsza to brakconst
odniesienia do aconst string*
, podczas gdy druga toconst
odniesienie do astring*
.T const&
abyconst T&
- jak @Justin Czas zwraca uwagę, są to różne typy. To może mieć żadnych konsekwencji czasami, ale w innych sytuacjach będzie to absolutnie niezbędne do preferowania jednego lub drugiego, podobnie jak preferowanieint
dodouble
.Zmień to na:
EDYTOWAĆ:
Nazywa się to
ref-to-pointer
i nie można przekazać adresu tymczasowego jako odniesienia do funkcji. (chyba że takconst reference
).Chociaż pokazałem
std::string* pS = &s;
(wskazałem na zmienną lokalną), jego typowym zastosowaniem byłoby: gdy chcesz, aby odbiorca zmienił sam wskaźnik, a nie obiekt, na który wskazuje. Na przykład funkcja przydzielająca pamięć i przypisująca adres bloku pamięci, którą zaalokowała do swojego argumentu, musi mieć odniesienie do wskaźnika lub wskaźnik do wskaźnika:źródło
&s
tworzy tymczasowy wskaźnik do łańcucha i nie możesz odwołać się do tymczasowego obiektu.źródło
Próbować:
lub
źródło
EDYCJA: trochę eksperymentowałem i odkryłem, że rzeczy są nieco subtelniejsze niż myślałem. Oto, co teraz uważam za dokładną odpowiedź.
&s
nie jest lwartością, więc nie można utworzyć do niej odwołania, chyba że jest to odniesienie do typuconst
. Na przykład nie możesz tego zrobićale możesz to zrobić
Jeśli umieścisz podobną deklarację w nagłówku funkcji, zadziała.
Jest jeszcze jedna kwestia, a mianowicie prowizoryczne. Zasada jest taka, że odwołanie do pliku tymczasowego można uzyskać tylko wtedy, gdy tak jest
const
. Więc w tym przypadku można by argumentować, że & s jest tymczasowe i dlatego musi być zadeklarowaneconst
w prototypie funkcji. Z praktycznego punktu widzenia nie ma to znaczenia w tym przypadku. (Jest to albo wartość r, albo wartość tymczasowa. Tak czy inaczej, obowiązuje ta sama reguła.) Jednakże, mówiąc ściśle, myślę, że nie jest to wartość tymczasowa, ale wartość r. Zastanawiam się, czy istnieje sposób na rozróżnienie tych dwóch. (Być może jest po prostu zdefiniowane, że wszystkie wartości tymczasowe są wartościami r, a wszystkie wartości inne niż l są tymczasowe. Nie jestem ekspertem w zakresie standardów).Biorąc to pod uwagę, twój problem jest prawdopodobnie na wyższym poziomie. Dlaczego chcesz podać adres
s
? Jeśli chcesz odwołać się do wskaźnika dos
, musisz zdefiniować wskaźnik, tak jak wJeśli chcesz mieć odniesienie
s
lub wskaźnik dos
, zrób prostą rzecz.źródło
Właśnie skorzystałem z odniesienia do wskaźnika, aby wszystkie wskaźniki w usuniętym drzewie binarnym z wyjątkiem katalogu głównego były bezpieczne. Aby wskaźnik był bezpieczny, musimy po prostu ustawić go na 0. Nie mogłem sprawić, aby funkcja, która usuwa drzewo (zachowując tylko korzeń), akceptowała odniesienie do wskaźnika, ponieważ używam korzenia (tego wskaźnika) jako pierwszego wejście do przejścia w lewo iw prawo.
Podsumowując, odwołanie do wskaźnika jest nieprawidłowe, gdy parametrem formalnym jest (ten) wskaźnik.
źródło
Witamy w C ++ 11 i referencjach rvalue:
Teraz masz dostęp do wartości wskaźnika (do którego odwołuje się
val
), czyli adresu ciągu.Możesz modyfikować wskaźnik i nikogo to nie obchodzi. To jest przede wszystkim jeden aspekt tego, czym jest wartość r.
Uważaj: wartość wskaźnika jest ważna tylko do momentu
myfunc()
powrotu. W końcu to tymczasowe.źródło
Wiem, że możliwe jest przekazywanie referencji wskaźników, zrobiłem to w zeszłym tygodniu, ale nie pamiętam, jaka była składnia, ponieważ Twój kod wygląda teraz poprawnie w moim mózgu. Jednak inną opcją jest użycie wskaźników wskaźników:
źródło
myfunc ("string * & val") to samo w sobie nie ma żadnego sensu. „string * & val” implikuje „string val”, * i & anulują się nawzajem. Wreszcie nie można przekazać zmiennej typu string do funkcji („string val”). Do funkcji można przekazywać tylko podstawowe typy danych, ponieważ inne typy danych muszą być przekazywane jako wskaźnik lub referencja. Do funkcji można przypisać string & val lub string * val.
źródło