[C++] Dubbio su costruttori impliciti
Buongiorno a tutti. Sto cercando di capire un fatto riguardante la costruzione implicita di un oggetto in c++.
Supponiamo di avere questa funzione :
Il problema è questo: se chiamo nel main la funzione impostaDimensione nei primi due modi funziona, mentre nel terzo no.
Sostanzialmente il mio dubbio è: perche con le liste di inizalizzazione avviene la conversione implicita tra i valori interi passati come argomento nella funzione verso i parametri del costruttore, mentre non avviene con le normali parentesi tonde?
Supponiamo di avere questa funzione :
void impostaDimensione(const Vec&);dove Vec è un oggetto definito in questo modo:
template <class T> class Vec { public: Vec(T a, T b); }
Il problema è questo: se chiamo nel main la funzione impostaDimensione nei primi due modi funziona, mentre nel terzo no.
void main() { impostaDimensione(Vec(10, 10)); // Primo modo impostaDimensione({10, 10}); // Secondo modo impostaDimensione(10, 10); // Oppure impostaDimensione((10, 10)); non funziona }
Sostanzialmente il mio dubbio è: perche con le liste di inizalizzazione avviene la conversione implicita tra i valori interi passati come argomento nella funzione verso i parametri del costruttore, mentre non avviene con le normali parentesi tonde?
Risposte
Perché [inline]impostaDimensione(10, 10)[/inline] viene visto come la chiamata alla funzione [inline]impostaDimensione(int, int)[/inline] che tu non hai definito da nessuna parte. Insomma se si permettesse la notazione che tu proponi, ci sarebbero forti problemi di ambiguità nel linguaggio. Nessuno ci capirebbe più nulla.
Riguardo invece a [inline]impostaDimensione((10, 10))[/inline] è un po' più complesso, ma sostanzialmente dovrebbe essere equivalente a chiamare [inline]impostaDimensione(10)[/inline]. Per capire come mai leggi qui.
Riguardo invece a [inline]impostaDimensione((10, 10))[/inline] è un po' più complesso, ma sostanzialmente dovrebbe essere equivalente a chiamare [inline]impostaDimensione(10)[/inline]. Per capire come mai leggi qui.
Credo di aver capito, ma ma se io avessi scritto
impostaDimensione(())e avendo nella classe Vec un costruttore di default, cmunque non lo avrei richiamato, se non scrivendo
impostaDimensione({})
Fondamentalmente, hanno usato le parentesi graffe perché quelle tonde avevano già altri usi e usarle in quelle posizioni sarebbe stato poco chiaro. Inoltre i costruttori con le parentesi graffe hanno un comportamento leggermente diverso da quelli con parentesi tonde. L'uso delle parentesi graffe è sempre stato usato, sin dal C, per l'inizializzazione delle variabili e il C99 aveva introdotto i Compound Literals che sono molto simili.
Grazie vict per i chiarimenti!