Czy podczas tworzenia zmiennych lokalnych należy używać (const) auto&
lub auto
?
na przykład:
SomeClass object;
const auto result = object.SomeMethod();
lub const auto& result = object.SomeMethod();
Gdzie SomeMethod () zwraca wartość inną niż pierwotna - być może inny typ zdefiniowany przez użytkownika. Rozumiem, że const auto& result
jest to poprawne, ponieważ wynik zwracany przez SomeMethod () wywołałby konstruktor kopiujący dla zwróconego typu. Proszę, popraw mnie jeśli się mylę.
A co z typami prymitywnymi? Zakładam, że const auto sum = 1 + 2;
ma rację.
Czy dotyczy to również zakresu opartego na pętlach?
for(const auto& object : objects)
auto
działa (z wyjątkiem osobliwego przypadkuinitializer_list
s, które są niededukowane w kontekście szablonu), a następnieauto
wpisz deduction.Odpowiedzi:
auto
iauto &&
obejmują większość przypadków:Użyj,
auto
gdy potrzebujesz lokalnej kopii. To nigdy nie przyniesie odniesienia. Konstruktor kopiujący (lub przenoszący) musi istnieć, ale może nie zostać wywołany z powodu optymalizacji kopiowania .Użyj,
auto &&
gdy nie obchodzi Cię, czy obiekt jest lokalny, czy nie. Technicznie rzecz biorąc, zawsze spowoduje to utworzenie referencji, ale jeśli inicjator jest tymczasowy (np. Funkcja zwraca wartość), będzie zachowywał się zasadniczo jak Twój własny obiekt lokalny.auto &&
Nie gwarantuje również, że obiekt będzie można modyfikować. Biorąc pod uwagęconst
przedmiot lub odniesienie, wywnioskujeconst
. Jednak często zakłada się modyfikowalność, biorąc pod uwagę specyficzny kontekst.auto &
iauto const &
są trochę bardziej szczegółowe:auto &
gwarantuje, że udostępniasz zmienną czemuś innemu. Jest to zawsze odniesienie, a nigdy tymczasowe.auto const &
jest podobnyauto &&
, ale zapewnia dostęp tylko do odczytu.Nie ma różnicy.
Tak. Stosując powyższe zasady,
auto &&
do modyfikowania i odrzucania wartości sekwencji w pętli. (To znaczy, chyba że kontener zapewnia widok tylko do odczytu, na przykładstd::initializer_list
w takim przypadku będzie to faktycznieauto const &
.)auto &
do modyfikowania wartości sekwencji w znaczący sposób.auto const &
aby uzyskać dostęp tylko do odczytu.auto
do pracy z kopiami (modyfikowalnymi).Wspominasz również
auto const
bez odniesienia. To działa, ale nie jest zbyt często używane, ponieważ rzadko istnieje korzyść z dostępu tylko do odczytu do czegoś, co już posiadasz.źródło
auto&
wydaje się być dobrym wyborem. Ale używaj,const auto&
gdy chcesz dodać stałość, której jeszcze nie ma.auto&&
służy do przekazywania, co moim zdaniem zdarza się częściej niż myśli Sutter. Na przykład, możesz chcieć zapisać wartość zwracaną przez,auto&&
a następnie „przekazać” ją do dwóch rzeczy, takich jak std :: cout, aby zobaczyć wartość do debugowania, a także przekazać ją do innej funkcji. Kiedyś częściej używałem auto &&, ale zostałem ugryziony raz lub dwa razy, gdy zrobił kilka nieoczekiwanych rzeczy. Żałuję, że nie zwróciłem większej uwagi na to, co poszło nie tak!auto&&
jest powiązany z brakującą funkcją językową, która powinna pozwolić na podzielenie dowolnego oświadczenia na mniejsze. Brakującą częścią jest przedłużenie żywotności… Włożyłem sporo wysiłku w naprawienie tego, ale nikt tego nie zauważył. Nie wkładaj zbyt wiele w punditry :)Tak, poprawne jest użycie
auto
iauto&
dla zmiennych lokalnych. Podczas uzyskiwania zwracanego typu funkcji również poprawne jest użycieauto&
. Dotyczy to również zakresu opartego na pętlach.Ogólne zasady użytkowania
auto
to:auto x
kiedy chcesz pracować z kopiami.auto &x
kiedy chcesz pracować z oryginalnymi elementami i możesz je modyfikować.auto const &x
kiedy chcesz pracować z oryginalnymi elementami i nie modyfikuj ich.Więcej informacji na temat specyfikacji automatycznej można znaleźć tutaj .
źródło
auto
używa tego samego mechanizmu dedukcji typu co szablony, z jedynym wyjątkiem, o którym wiem, że jest to lista inicjująca nawiasy klamrowe, które są wywnioskowane przezauto
asstd::initializer_list
, ale nie są wywnioskowane w kontekście szablonu.auto x = expression;
działa najpierw usuwając wszystkie kwalifikatory odwołania i cv z typu wyrażenia po prawej stronie, a następnie dopasowując typ. Na przykład, jeśli masz
const int& f(){...}
toauto x = f();
dedukujex
jakoint
, a nieconst int&
.Druga forma,
auto& x = expression
nie usuwa kwalifikatorów cv, więc korzystając z powyższego przykładu,
auto& x = f()
wnioskujex
jakoconst int&
. Pozostałe kombinacje po prostu dodają kwalifikatory cv.Jeśli chcesz, aby typ był zawsze wywnioskowany za pomocą kwalifikatorów cv-ref, użyj niesławnego
decltype(auto)
w C ++ 14, który używadecltype
reguł odliczania typów.Więc w skrócie, jeśli chcesz kopiować, użyj
auto
, jeśli chcesz odniesienia, użyjauto&
. Używajconst
zawsze, gdy chcesz mieć więcejconst
.EDYTUJ Istnieje dodatkowy przypadek użycia,
auto&& x = expression;
który wykorzystuje reguły zwijania referencji, takie same jak w przypadku przekazywania odwołań w kodzie szablonu. Jeśli
expression
jest lwartością, tox
jest odwołaniem do lwartości z kwalifikatorami cvexpression
. Jeśliexpression
jest wartością r, tox
jest odniesieniem do wartości r.źródło
rvalues
. Czy istnieje prosty sposób testowania? Jak możesz mieć rvalue kwalifikowaną do CV? Po powrocie funkcji cv jest odrzucane.auto && x = std::move< const int >( 5 );
zadeklarująint const && x
, chociaż są rzadko używane.Tak. Auto to nic innego jak typ wywodzący się z kompilatora, więc używaj odwołań tam, gdzie normalnie używasz referencji, oraz lokalnych (automatycznych) kopii, w których normalnie używasz kopii lokalnych. To, czy użyć odwołania, czy nie, jest niezależne od dedukcji typu.
Prawny? Tak, z konst. Najlepsze praktyki? Prawdopodobnie nie, nie. Przynajmniej nie w C ++ 11. Zwłaszcza jeśli wartość zwrócona przez SomeMethod () jest już tymczasowa. Będziesz chciał dowiedzieć się więcej o semantyce przenoszenia w C ++ 11, elizji kopiowania i optymalizacji wartości zwracanej: https://juanchopanzacpp.wordpress.com/2014/05/11/want-speed-dont-always-pass-by- wartość/
http://www.informit.com/guides/content.aspx?g=cplusplus&seqNum=199
https://isocpp.org/wiki/faq/ctors#return-by-value-optimization
Tak, w porządku.
Tak, to też jest w porządku. Cały czas piszę taki kod w pracy.
źródło