Domanda

C'è qualche buona ragione per cui un set vuoto di parentesi tonde (parentesi) non è valido per chiamare il costruttore predefinito in C ++?

MyObject  object;  // ok - default ctor
MyObject  object(blah); // ok

MyObject  object();  // error

Mi sembra di digitare " () " automaticamente ogni volta. C'è una buona ragione per cui questo non è permesso?

È stato utile?

Soluzione

Analisi più irritante

Questo è correlato a ciò che è noto come l'analisi più irritante di "C ++". Fondamentalmente, tutto ciò che può essere interpretato dal compilatore come una dichiarazione di funzione verrà interpretato come una dichiarazione di funzione.

Un'altra istanza dello stesso problema:

std::ifstream ifs("file.txt");
std::vector<T> v(std::istream_iterator<T>(ifs), std::istream_iterator<T>());

v viene interpretato come una dichiarazione di funzione con 2 parametri.

La soluzione alternativa è aggiungere un'altra coppia di parentesi:

std::vector<T> v((std::istream_iterator<T>(ifs)), std::istream_iterator<T>());

Oppure, se si dispone di C ++ 11 e inizializzazione elenco (nota anche come inizializzazione uniforme) disponibile:

std::vector<T> v{std::istream_iterator<T>{ifs}, std::istream_iterator<T>{}};

In questo modo, non è possibile interpretarlo come una dichiarazione di funzione.

Altri suggerimenti

Perché è considerato come la dichiarazione di una funzione:

int MyFunction(); // clearly a function
MyObject object(); // also a function declaration

La stessa sintassi viene utilizzata per la dichiarazione di funzione - ad es. la funzione oggetto , non prendendo parametri e restituendo MyObject

Perché il compilatore pensa che sia una dichiarazione di una funzione che non accetta argomenti e restituisce un'istanza MyObject.

Suppongo che il compilatore non saprebbe se questa affermazione:

  

Oggetto MyObject ();

è una chiamata del costruttore o un prototipo di funzione che dichiara una funzione denominata oggetto con tipo di ritorno MyObject e senza parametri.

Puoi anche usare il modo più dettagliato di costruire:

MyObject object1 = MyObject();
MyObject object2 = MyObject(object1);

In C ++ 0x questo consente anche auto :

auto object1 = MyObject();
auto object2 = MyObject(object1);

Come accennato più volte, è una dichiarazione. È così per la compatibilità con le versioni precedenti. Una delle molte aree del C ++ che sono sciocche / incoerenti / dolorose / fasulle a causa della sua eredità.

Da n4296 [dcl.init]:

  

[Nota:
Poiché () non è consentito dalla sintassi per inizializzatore ,    X a (); non è la dichiarazione di un oggetto di classe X, ma il   dichiarazione di una funzione non prendendo argomenti e restituendo una X.   form () è consentito in alcuni altri contesti di inizializzazione (5.3.4,   5.2.3, 12.6.2).   
& # 8212; nota di fine]

Come hanno detto gli altri, è una dichiarazione di funzione. Dal C ++ 11 puoi usare l'inizializzazione del controvento se hai bisogno di vedere il qualcosa vuoto che ti dice esplicitamente che viene usato un costruttore predefinito.

Jedi luke{}; //default constructor
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top