2013-03-13 15 views
6

Semplice domanda sulla sintassi C++ 11. C'è un codice di esempio (ridotto uno da source)Chiamare ctor con le parentesi graffe

struct Wanderer 
{ 
    explicit Wanderer(std::vector<std::function<void (float)>> & update_loop) 
    { 
    update_loop.emplace_back([this](float dt) { update(dt); }); 
    } 
    void update(float dt); 
}; 

int main() 
{ 
    std::vector<std::function<void (float)>> update_loop; 
    Wanderer wanderer{update_loop}; // why {} ??? 
} 

Mi piacerebbe sapere, come può essere possibile costruttore di chiamata con parentesi graffe come Wanderer wanderer{update_loop}; Non è né lista di inizializzazione, né l'inizializzazione uniforme. Qual è la cosa è questa?

+0

Ma è l'inizializzazione uniforme. Le parentesi possono essere utilizzate per chiamare i costruttori, sebbene il costruttore che prende una 'std :: initializer_list' di quel tipo sia sempre preferito. – chris

+0

'// perché {} ???' - Buona domanda. Non c'è ragione di preferirlo su "Wanderer wanderer (update_loop)". – ipc

+1

@ipc In alcuni casi, può evitare l'analisi più irritante. – juanchopanza

risposta

13

Non è né l'elenco di inizializzazione né l'inizializzazione uniforme. Qual è la cosa è questa?

Il vostro locale è sbagliato. È un'inizializzazione uniforme e, in termini standard, inizializzazione di parentesi diretta.

A meno che non sia presente un costruttore che accetta un std::initializer_list, utilizzare le parentesi per la costruzione di oggetti equivale a utilizzare le parentesi.

Il vantaggio di usare le parentesi è che la sintassi è immune al problema Most Vexing Parse:

struct Y { }; 

struct X 
{ 
    X(Y) { } 
}; 

// ... 

X x1(Y()); // MVP: Declares a function called x1 which returns 
      // a value of type X and accepts a function that 
      // takes no argument and returns a value of type Y. 

X x2{Y()}; // OK, constructs an object of type X called x2 and 
      // provides a default-constructed temporary object 
      // of type Y in input to X's constructor. 
1

È solo C++ 11 sintassi. È possibile inizializzare oggetti chiamando il costruttore con parentesi graffe. Devi solo ricordare che se il tipo ha un costruttore initializer_list, quello ha la precedenza.

Problemi correlati