Jakie są zalety / wady używania auto
słowa kluczowego, szczególnie w przypadku pętli?
for(std::vector<T>::iterator it = x.begin(); it != x.end(); it++ )
{
it->something();
}
for(std::map<T>::iterator it = x.begin(); it != x.end(); it++ )
{
it->second->something();
}
for(auto it = x.begin(); it != x.end(); it++ )
{
it->??
}
Wygląda na to, jeśli nie wiem, czy masz iterator na mapie lub wektor ty nie wiesz, czy użyć first
lub second
czy tylko bezpośrednio właściwości dostępu obiektu, nie?
To przypomina mi debatę C # na temat tego, czy użyć słowa kluczowego var
. Mam wrażenie, że do tej pory mam wrażenie, że w świecie C ++ ludzie są gotowi na przyjęcie auto
słowa kluczowego bez większego wysiłku niż var
w świecie C #. Moim pierwszym instynktem jest to, że lubię znać typ zmiennej, aby wiedzieć, jakie operacje mogę na niej wykonać.
var
? Tęsknie za tym.for (auto& it : x)
(lub bez odniesienia, jeśli chcesz skopiować)x
a nawet nie wiesz, co tox
jest, nie powinieneś pisać tej pętli w pierwszej kolejności ;-)Odpowiedzi:
Motywacje w C ++ są bardziej ekstremalne, ponieważ typy mogą stać się znacznie bardziej skomplikowane i złożone niż typy C # z powodu metaprogramowania i innych rzeczy.
auto
jest szybszy w pisaniu i czytaniu oraz bardziej elastyczny / łatwy w utrzymaniu niż typ jawny. Mam na myśli, czy chcesz zacząć pisać?To nie jest nawet pełny typ. Opuściłem kilka argumentów szablonu.
źródło
auto
jest. Przez projekt.typedef
pomaga, aleauto
pomaga więcej.W twoim przykładzie:
musi być deklaracja
x
widoczna. Dlatego rodzajit
powinien być oczywisty. Jeśli typx
nie jest oczywisty, wówczas metoda jest za długa lub klasa jest za duża.źródło
x
jest to bardzo zła nazwa zmiennej do pojemnika. W niektórych sytuacjach najprawdopodobniej możesz po prostu spojrzeć na (semantycznie cenną) nazwę i wywnioskować możliwe operacje.x
jako ogólny przykład, zwykle używam dość opisowych nazw zmiennych.Sprzeciw ! Załadowane pytanie.
Czy możesz mi wyjaśnić, dlaczego zawiera trzeci kod
??
, a pierwszy i drugi nie? W trosce o sprawiedliwość kod musi mieć następujące brzmienie:Tam. Ten sam problem, nawet jeśli nie korzystałeś
auto
.I we wszystkich przypadkach odpowiedź jest taka sama: kontekst ma znaczenie . Nie możesz w sposób znaczący mówić o kawałku kodu w izolacji. Nawet jeśli nie używałeś szablonów, ale jakiś konkretny typ, problem przesunąłby to tylko gdzie indziej, ponieważ czytelnik twojego kodu musiałby wiedzieć o deklaracji tego typu.
Jeśli użycie
auto
w takich sytuacjach spowoduje, że Twój kod będzie nieczytelny, powinieneś traktować to jako znak ostrzegawczy, że coś jest nie tak z projektem kodu. Oczywiście zdarzają się przypadki, w których istotne są szczegóły niskiego poziomu (na przykład w przypadku operacji bitowych lub starszego interfejsu API), w których wyraźny typ może poprawić czytelność. Ale ogólnie - nie.Jeśli chodzi o
var
(ponieważ wyraźnie o tym wspomniałeś), istnieje również szeroki konsensus w społeczności C # w zakresie używaniavar
. Argumenty przeciwko jego stosowaniu są zwykle oparte na błędach .źródło
T
jest nieprzezroczysty dla użytkownika jakoauto
. Ale jedno powinno być w porządku, a drugie nie ?! To nie ma sensu. W przypadku OPT
jest to stand-in dla dowolnego typu. W prawdziwym kodzie może to być użycie szablonów(for typename std::vector<T>::iterator…)
lub interfejsu klasowego. W obu przypadkach rzeczywisty typ jest ukryty przed użytkownikiem, a mimo to rutynowo piszemy taki kod bez problemów.auto
. To proste, aby zobaczyć, jakie operacjex
obsługują z kontekstu. W rzeczywistości ten typ nie zawiera żadnych dodatkowych informacji: w obu przypadkach potrzebujesz trochę dodatkowej wiedzy (IDE, dokumentacji, wiedzy / pamięci), aby podać zestaw obsługiwanych operacji.begin
powraca, ale nie wiem costd::vector<>::iterator
jest. I musisz użyć złego narzędzia programistycznego, które nie może dać ci tych informacji w sposób trywialny. To jest bardzo skomplikowane. W rzeczywistości znasz jedno lub drugiebegin
iiterator
powinieneś używać IDE lub edytora, który może łatwo udostępnić ci odpowiednie informacje. Każdy nowoczesny edytor IDE i programista może to zrobić.ZAWODOWIEC
Twój kod :
nie będzie się kompilować z powodu nazwy zależnej od szablonu.
Oto poprawna składnia:
Teraz spójrz, jak długo trwa deklaracja typu. To wyjaśnia, dlaczego
auto
słowo kluczowe zostało wprowadzone. To:jest bardziej zwięzły. To jest zawodowiec.
KON
Musisz być trochę ostrożny. Za pomocą słowa kluczowego
auto
otrzymujesz zadeklarowany typ.Na przykład :
vs
Podsumowując: tak, powinieneś to zrobić, ale nie nadużywaj go. Niektórzy ludzie używają go zbyt często i wszędzie ustawiają auto, jak w następnym przykładzie:
vs
źródło
auto i = 0
. Winny. Robię to. Ale to dlatego, że wiem, że0
jest to literał typuint
. (i stała ósemkowa ;-))Tak, powinieneś!
auto
nie usuwa tego typu; nawet jeśli „nie wiesz”, co tox.begin()
jest, kompilator wie i zgłosi błąd, jeśli spróbujesz nieprawidłowo użyć tego typu. Ponadto emulacja zamap
pomocą a nie jest niczym niezwykłymvector<pair<Key,Value>>
, więc użycie koduauto
będzie działać dla obu reprezentacji słownikowych.źródło
Tak, powinieneś użyć
auto
jako domyślnej reguły. Ma surowe zalety w porównaniu z jawnym określaniem typu:Tutaj masz wybór. Są też przypadki, w których nie masz wyboru:
Pod warunkiem, że dokładnie wiesz, co
auto
robi, nie ma żadnych wad.źródło