Vector & initializer list - dlaczego ten kod w ogóle działa?

0

Napotkałem taki kod w pytaniu na http://cppquiz.org/quiz/question/107:

#include <iostream>
#include <vector>

int f() { std::cout << "f"; return 0;}
int g() { std::cout << "g"; return 0;}

void h(std::vector<int> v) {}

int main() {
    h({f(), g()});
}

I mam pytanie, dlaczego w momencie użycia funkcji h program się w ogóle kompiluje?
Funkcja h wymaga przecież przesłania vectora, a w tym przypadku podajemy listę inicjalizacyjną (poprawcie, jeśli się mylę), więc czemu to działa?
Niech jakiś dobry człowiek objaśni, bo nie rozumiem :(

3

Od początku. uniform initialization to nie typ. W zależności od miejsca użycia {} może oznaczać coś innego. W szczególności może to oznaczać list-initialization
std::vector ma konstruktor, który przyjmuje std::initialization_list i to on zostanie dopasowany w tym przykładzie.

W zadaniu pytają o to, czy {} wprowadza reguły kolejności inicjalizacji składowych. I odpowiedź brzmi tak, wprowadza. W przeciwieństwie do wywołania funkcji porządek inicjalizacji elementów {} jest zdeterminowany. Elementy są inicjowane w kolejności występowania (od lewej do prawej).

Warto zastanowić się nad czymś zupełnie innym. Mianowicie, "siła" {} przy overload resolution. I tutaj jest ciekawie. Dziad łapie wszystko co tylko możliwe. W tym przykładzie z zadania np. zostanie wywołany konstruktor vectora z std::initializer_list, a nie np. konstruktor przyjmujący liczbę elementów i wartość tych elementów. Jeszcze ciekawiej jest gdy klasa ma konstruktor z std::initializer_list<X> i np. konstruktor przyjmujący X i Y, gdzie Y nie ma implicit konwersji do X i spróbujemy utworzyć obiekt tej klasy w taki sposób foo f{1, "bar");

Ogólnie temat type deduction to najciekawsza rzecz w C++ ; p

1 użytkowników online, w tym zalogowanych: 0, gości: 1