2015-07-07 21 views
8

Poniżej cytat z skutecznych, nowoczesnych C++ (strona 55):Czy puste nawiasy wywołują domyślny konstruktor lub konstruktor pobierający std :: initializer_list?

„Załóżmy, że używasz pusty zestaw szelki do budowy obiektu, który obsługuje domyślnego konstruktora a także obsługuje std :: initializer_list budowę Co oznaczają puste klamry? Itp. Zasadą jest, że otrzymujesz domyślną konstrukcję. "

Próbowałem to z std :: tablicy:

std::array<int, 10> arr{}; 

i dostał ostrzeżenie od g ++ (wersja 4.8.2):

ostrzegawczy: brakuje inicjator dla członka „std: : array < int, 10ul> :: _ M_elems '

co jest ostrzeżeniem, które pojawia się przy próbie zbudowania std::array z pustego std::initializer_list (zobacz Why can I initialize a regular array from {}, but not a std::array, aby uzyskać omówienie tego ostrzeżenia).

Dlaczego więc powyższy wiersz kodu nie jest interpretowany jako wywołujący domyślny konstruktor?

+0

'std :: array' nie ma konstruktora pobierającego' std :: initializer_list', a inicjator, który tu masz, nie jest też 'std :: initailizer_list'. Jest to lista wzmocniona-inicjująca. Nie jestem pewien, dlaczego otrzymujesz ostrzeżenie, ponieważ używanie pustych klamerek powinno być wartościowe - zainicjuj zagnieżdżoną tablicę. – 0x499602D2

+0

@ 0x499602D2 zobacz moją odpowiedź na powiązane pytanie, gcc był agresywny, a późniejsze wersje gcc nie generują ostrzeżenia. –

+0

Należy również zauważyć, że zmienili standard C++ 11 w znaczący sposób w środowisku DR. Rzeczywisty standard mówi jedno, ale od kompilatorów oczekuje się czegoś zupełnie innego. – o11c

Odpowiedz

8

To dlatego std::array jest agregatem a zatem aggregate initialization wykonywana jest to ujęte w sekcji 8.5.4[dcl.init.list] który mówi draft C++11 standard:

Lista inicjalizacja obiektu lub odniesienie typu T jest zdefiniowany następująco:

  • Jeśli lista inicjator ma żadnych elementów, a T jest typem klasy z domyślnego konstruktora, obiekt jest zainicjalizowana wartość.

  • W przeciwnym razie, jeżeli T jest agregatem, wykonywana jest inicjalizacja zbiorcza (8.5.1).

    double ad[] = { 1, 2.0 }; // OK 
    int ai[] = { 1, 2.0 }; // error: narrowing 
    
    struct S2 { 
        int m1; 
        double m2, m3; 
    }; 
    
    S2 s21 = { 1, 2, 3.0 }; // OK 
    S2 s22 { 1.0, 2, 3 }; // error: narrowing 
    S2 s23 { }; // OK: default to 0,0,0 
    

i możemy zobaczyć, czy nie jest to agregat następnie lista jest długa i mówi:

  • W przeciwnym razie, jeśli T jest specjalizacja std :: initializer_list , obiekt initializer_list to zbudowany w sposób opisany poniżej i użyty do zainicjowania obiektu zgodnie z regułami inicjowania obiektu z klasy tego samego typu (8.5).
  • W przeciwnym razie, jeśli T jest typem klasy, rozważane są konstruktorzy. Odpowiednie konstruktory są wymienione na , a najlepsze wybiera się poprzez rozdzielczość przeciążenia (13.3, 13.3.1.7). Jeśli konwersja któregokolwiek z argumentów wymaga zwężenia konwersji (zob. poniżej), program jest źle sformułowany.

Można potwierdzić std::array jest agregatem z sekcji 23.3.2.1[array.overview]:

Tablica jest agregat (8.5.1), który może być inicjowany składni

array<T, N> a = { initializer-list }; 

gdzie lista inicjalizatora jest rozdzielaną przecinkami listą maksymalnie N elementów , których typy są zamienne z T.

części 8.5.1 odwołanie jest 8.5.1 kruszywa [dcl.init.aggr] i mówi:

gdy agregat jest inicjowany przez liście inicjatora, jak określono w wersji 8.5.4, elementy listy inicjalizującej są traktowane jako inicjatory dla członków agregatu, w rosnącej pozycji podrzędnej lub zamówienie członka [...]

. Wracamy do sekcji 8.5.4, od której zaczęliśmy.

+0

Czy mógłbyś podać link do standardowego dokumentu, który zacytowałeś (o ile jest on oczywiście dostępny)? – AlwaysLearning

+0

@MeirGoldenberg dodał link do odpowiedzi, możesz zobaczyć [Gdzie mogę znaleźć aktualne dokumenty standardowe C lub C++?] (Http://stackoverflow.com/questions/81656/where-do-i-find-the- dokumenty bieżące-c-lub-c-standardowe), które zawierają listę wszystkich wersji roboczych dostępnych publicznie. –