Z całego materiału, którego używałem do nauki C ++, auto
zawsze był dziwny specyfikator czasu przechowywania, który nie służył żadnemu celowi. Ale niedawno napotkałem kod, który używał go jako nazwy typu. Spróbowałem z ciekawości i przyjmuje on rodzaj tego, co mu przydzielę!
Nagle iteratory STL i, cóż, wszystko, co używa szablonów, jest 10-krotnie łatwiejsze do napisania. Mam wrażenie, że używam „zabawnego” języka, takiego jak Python.
Gdzie to słowo kluczowe było przez całe moje życie? Czy możesz przerwać moje marzenia, mówiąc, że jest dostępny wyłącznie dla studia wizualnego, czy nie jest przenośny?
Odpowiedzi:
auto
było słowem kluczowym, które C ++ „odziedziczyło” po C, które istniało prawie od zawsze, ale praktycznie nigdy nie było używane, ponieważ były tylko dwa możliwe warunki: albo było niedozwolone, albo było zakładane domyślnie.Użycie
auto
do oznaczania wydedukowanego typu było nowe w C ++ 11.Jednocześnie
auto x = initializer
dedukuje typx
z typu winitializer
taki sam sposób, jak działa dedukcja typu szablonu dla szablonów funkcji. Rozważmy taki szablon funkcji:W punkcie A przypisano typ na
T
podstawie wartości przekazanej dla parametru dowhatever
. Kiedy to zrobiszauto x = initializer;
, ta sama dedukcja typu jest używana do określenia typu nax
podstawie typuinitializer
użytego do jego zainicjowania.Oznacza to, że większość mechanizmów dedukcji typów, które kompilator musi zaimplementować,
auto
była już obecna i używana w szablonach na każdym kompilatorze, który nawet próbował zaimplementować C ++ 98/03. W związku z tym dodanie obsługi programuauto
było pozornie dość łatwe dla zasadniczo wszystkich zespołów kompilatorów - zostało dodane dość szybko i wydaje się, że było też kilka błędów z nim związanych.Kiedy ta odpowiedź została pierwotnie napisana (w 2011 roku, zanim tusz wysechł w standardzie C ++ 11)
auto
był już dość przenośny. Obecnie jest całkowicie przenośny wśród wszystkich głównych kompilatorów. Jedynymi oczywistymi powodami, aby tego uniknąć, byłoby napisanie kodu zgodnego z kompilatorem C lub konkretna potrzeba kierowania na jakiś niszowy kompilator, o którym wiesz, że go nie obsługuje (np. Kilka osób nadal pisze kod dla MS-DOS przy użyciu kompilatorów firm Borland, Watcom itp., które nie widziały znaczących ulepszeń od dziesięcioleci). Jeśli używasz w miarę aktualnej wersji któregokolwiek z głównych kompilatorów, nie ma powodu, aby w ogóle tego unikać.źródło
Po prostu bierze ogólnie bezużyteczne słowo kluczowe i nadaje mu nową, lepszą funkcjonalność. Jest standardem w C ++ 11 i większość kompilatorów C ++ nawet z pewną obsługą C ++ 11 będzie go obsługiwać.
źródło
W przypadku zmiennych określa, że typ deklarowanej zmiennej zostanie automatycznie wydedukowany z jej inicjatora. W przypadku funkcji określa, że typ zwracany jest końcowym typem zwracanym lub zostanie wydedukowany z jego instrukcji powrotu (od C ++ 14).
Składnia
Wyjaśnienie
1) Podczas deklarowania zmiennych w zakresie blokowym, w zakresie przestrzeni nazw, w instrukcjach inicjalizacji pętli for itp. Jako specyfikatora typu można użyć słowa kluczowego auto. Po określeniu typu inicjatora kompilator określa typ, który zastąpi słowo kluczowe auto, korzystając z reguł dedukcji argumentów szablonu z wywołania funkcji (szczegółowe informacje można znaleźć w temacie dedukcja argumentów szablonu # Inne konteksty). Słowa kluczowego auto mogą towarzyszyć modyfikatory, takie jak const lub &, które będą uczestniczyć w dedukcji typu. Na przykład, biorąc pod uwagę
const auto& i = expr;
, typ i jest dokładnie typem argumentu u w wyimaginowanym szablonie,template<class U> void f(const U& u)
jeśli wywołanie funkcjif(expr)
został skompilowany. W związku z tym auto && można wywnioskować jako odniesienie l-wartości lub odniesienie r-wartości zgodnie z inicjatorem, który jest używany w pętli for na podstawie zakresu. Jeśli do zadeklarowania wielu zmiennych używane jest auto, wywnioskowane typy muszą być zgodne. Na przykład deklaracjaauto i = 0, d = 0.0;
jest źle sformułowana, podczas gdy deklaracjaauto i = 0, *p = &i;
jest poprawnie sformułowana, a auto jest wywnioskowane jako int.2) W deklaracji funkcji, która używa końcowej składni zwracanego typu, słowo kluczowe auto nie wykonuje automatycznego wykrywania typu. Służy tylko jako część składni.
3) W deklaracji funkcji, która nie używa końcowej składni zwracanego typu, słowo kluczowe auto wskazuje, że typ zwracany zostanie wydedukowany z argumentu operacji instrukcji return przy użyciu reguł dedukcji argumentów szablonu.
4) Jeśli zadeklarowanym typem zmiennej jest decltype (auto), słowo kluczowe auto jest zastępowane wyrażeniem (lub listą wyrażeń) jego inicjatora, a rzeczywisty typ jest wywnioskowany przy użyciu reguł dla decltype.
5) Jeśli zwracany typ funkcji jest zadeklarowany jako decltype (auto), słowo kluczowe auto jest zastępowane operandem instrukcji return, a rzeczywisty typ zwracania jest wywnioskowany przy użyciu reguł dla decltype.
6) Zagnieżdżony specyfikator nazwy w postaci auto :: jest symbolem zastępczym, który jest zastępowany klasą lub typem wyliczenia zgodnie z regułami odliczania symboli zastępczych typu ograniczonego.
7) Deklaracja parametru w wyrażeniu lambda. (od C ++ 14) Deklaracja parametru funkcji. (koncepcje TS)
Uwagi Do C ++ 11, auto miało semantykę specyfikatora czasu przechowywania. Mieszanie zmiennych automatycznych i funkcji w jednej deklaracji, jak w,
auto f() -> int, i = 0;
jest niedozwolone.Więcej informacji: http://en.cppreference.com/w/cpp/language/auto
źródło
Tej funkcjonalności nie było przez całe Twoje życie. Jest obsługiwany w programie Visual Studio od wersji 2010. Jest to nowa funkcja C ++ 11, więc nie jest wyłączna dla programu Visual Studio i jest / będzie przenośna. Większość kompilatorów już to obsługuje.
źródło
Nigdzie nie idzie ... to nowa standardowa funkcja C ++ w implementacji C ++ 11. Biorąc to pod uwagę, chociaż jest to wspaniałe narzędzie do upraszczania deklaracji obiektów, a także do czyszczenia składni niektórych paradygmatów wywołań (tj. Pętli for opartych na zakresie), nie nadużywaj / nadużywaj tego :-)
źródło
Słowo kluczowe auto określa, że typ deklarowanej zmiennej zostanie automatycznie odjęty od jej inicjatora. W przypadku funkcji, jeśli ich typem zwracanym jest auto, to zostanie to ocenione przez wyrażenie typu zwracanego w czasie wykonywania.
Może to być bardzo przydatne, gdy musimy użyć iteratora. Na przykład dla poniższego kodu możemy po prostu użyć "auto" zamiast pisać całą składnię iteratora.
W ten sposób możemy użyć słowa kluczowego „auto”
źródło
To magia to możliwość ograniczenia konieczności pisania kodu dla każdego typu zmiennej przekazywanej do określonych funkcji. Rozważmy podobną do Pythona funkcję print () w jej bazie C.
źródło