2011-11-25 15 views
18
#include <vector> 
#include <iostream> 

int main() 
{ 
    std::vector<int> v = { 1, 2, 3 }; 
    for (auto it : v) 
    { 
     std::cout<<it<<std::endl; 
    } 
} 

Co to jest auto rozwijanie? Czy rozszerza się do int& lub int?Jaki typ znajduje się w zakresie pętli?

+0

Historycznie słowo kluczowe auto było typem pamięci typu specyfikator wskazujący obiekt, który ma automatyczny typ przechowywania (tj. Przydzielony na stosie). – Oyeme

+9

@Oyeme: Pewnie. Ale jak to jest związane z pytaniem? – ereOn

+5

@Oyeme: W C++ 11, 'auto' oznacza coś zupełnie nowego. –

Odpowiedz

18

Rozciąga się na wartość int. Jeśli chcesz odniesienia, można użyć

for (auto& it : v) 
{ 
    std::cout<<it<<std::endl; 
} 

Według standardu C++ 11, auto liczy się jako prosty typu specyfikatorem [7.1.6.2], a więc te same zasady odnoszą się do niego jako innym prostym specyfikatorom typu . Oznacza to, że zadeklarowanie referencji pod numerem auto nie różni się niczym od niczego.

+0

Możesz chcieć dodać odniesienie do standardu (wybacz kalambur) dla kompletności. – wilhelmtell

+0

@JohnDibling Myślę, że źle rozumiesz tę funkcję. 'it' nie jest int, ponieważ kontener' v' ma pewną liczbę elementów, które znajdują się w zakresie 'int', ale ponieważ' v' zawiera ints. Jeśli zawiera elementy 'SomeClass', typem' it' będzie 'SomeClass'. –

+0

@wilhelmtell Dobra sugestia, ale nie znalazłem żadnej wyraźnej wzmianki o referencjach z automatyczną specyfikacją ani deklaracjami dla zakresu (właśnie sprawdziłem: 6.5.4 i 7.1.6.4 w standardzie). Myślę, że naturalnie wynika to z tego, że typ został wydedukowany i użyty zamiast "auto". Można też napisać 'auto & it'. –

5

Stworzyłem inny przykład, który odpowiada na pytanie:

#include <vector> 
#include <iostream> 

struct a 
{ 
    a() { std::cout<<"constructor" << std::endl; } 
    a(const a&) { std::cout<<"copy constructor" << std::endl; } 
    a(a&&) { std::cout<<"move constructor" << std::endl; } 

    operator int(){return 0;} 
}; 

int main() 
{ 
    std::vector<a> v = { a(), a(), a() }; 

    std::cout<<"loop start" << std::endl; 
    for (auto it : v) 
    { 
     std::cout<< static_cast<int>(it)<<std::endl; 
    } 
    std::cout<<"loop end" << std::endl; 
} 

Jest oczywiste, że auto rozszerza się int, a kopia jest dokonywana. Aby zapobiec kopiowaniu, pętla for musi mieć odniesienie:

for (auto & it : v) 
+0

To nie odpowiada na pytanie, tylko pokazuje, jak zachowuje się twój kompilator. – wilhelmtell

+0

Myślę, że to odpowiada, kompilator powinien postępuj zgodnie ze standardem, a VJo złożył prawie dokładnie tę samą odpowiedź, co ja, w tym samym momencie, usunął ją i dostarczył bardziej kompletną, więc nie ma za co. jodła ul. –

Powiązane problemy