2015-12-31 10 views
8

Przeglądałem jakiś kod napisany dla projektu szkolnego, który przy bliższej inspekcji wyglądał dla mnie dziwnie. Miałem klasę podobny do poniższego:Przesyłanie ciągu znaków do wektora obiektów

class Foo { 
public: 
    Foo(std::string s) : _s(s) {} 
private: 
    std::string _s; 
}; 

int main() { 
    std::string str = "Hiyo"; 

    std::vector<Foo> f; 
    f.push_back(str); // Compiles. Weird to me though. 
    f.push_back(Foo(str)); // Predictably, this compiles as well. 

    return 0; 
} 

dlaczego pierwsze wywołanie push_back ważna wypowiedź, choć str nie jest Foo?

Odpowiedz

16

klasy Foo ma bez wyraźnej konstruktor realizacji jednego argumentu typu std::string (tj Converting constructor), co oznacza, że ​​może być pośrednio odlewano z std::string.

f.push_back(str);  // implicit casting from std::string to Foo 
f.push_back(Foo(str)); // explicit casting from std::string to Foo 

Uwaga jeśli dokonać explicit konstruktor, niejawny odlewania będą zakazane.

class Foo { 
public: 
    explicit Foo(std::string s) : _s(s) {} 
// ~~~~~~~~ 
private: 
    std::string _s; 
}; 

a następnie

f.push_back(str);  // invalid now 
f.push_back(Foo(str)); // still valid 
+1

To powinna być zaakceptowana odpowiedź, ponieważ mówi o "wyraźnym" – CinCout

7

Pierwsze odepchnięcie automatycznie zainicjalizuje obiekt Foo, biorąc pod uwagę obiekt string; poprzez twoją listę inicjalizującą.

(Oczekuje obiektu Foo, otrzymuje ciąg znaków: czy obiekt Foo można zainicjować za pomocą pojedynczego ciągu znaków? Tak, lista inicjalizatorów ma pojedynczy element i obiekt jest inicjowany z tego elementu).

uzyskać szczegółowe informacje, patrz np .:

+2

Lista inicjatora nie powinny być znaczące. Nadal będzie się kompilował bez niego. – ChrisD

+1

Co jeśli 'Foo (std :: string s)' jest 'jawne'? – CinCout

2

Myślę, że w pierwszej pushback jest automatycznie inicjuje Foo(str) więc jego basicaly tha sam!

Powiązane problemy