Most vexing parse: differenze tra le versioni

Contenuto cancellato Contenuto aggiunto
LauBot (discussione | contributi)
m Bot: passaggio degli url da HTTP a HTTPS
KSavys (discussione | contributi)
Funzionalità collegamenti suggeriti: 3 collegamenti inseriti.
 
(3 versioni intermedie di 3 utenti non mostrate)
Riga 1:
Il '''most vexing parse''' è una forma di soluzione di [[grammatica ambigua|ambiguità sintattica]] del [[C++]], definita nella sezione 8.2 dello standard.<ref name="C++03 8.2">[[International Organization for Standardization|ISO]]/[[International Electrotechnical Commission|IEC]] (2003). ''[[C++#Language standard|ISO/IEC 14882:2003(E): Programming Languages - C++]] §8.2 Ambiguity resolution [dcl.ambig.res]''</ref>, determinata dal fatto che la [[sintassi]] per l'inizializzazione di una variabile è in alcuni casi ambigua con quella di dichiarazione di una funzione. La locuzione ''most vexing parse'' è stata introdotta da [[Scott Meyers]] in ''Effective STL'' (2001).<ref name="effectivestl">{{Cita libro|nome= Scott
|cognome= Meyers
|wkautore= Scott Meyers
|anno= 2001
|titolo= Effective STL: 50 Specific Ways to Improve Your Use of the Standard Template Library
|url= https://archive.org/details/effectivestl50sp0000meye
|editore= Addison-Wesley
| isbn = 0-201-74962-9
Riga 10 ⟶ 11:
== Esempio con classi e oggetti ==
Il seguente è un esempio di dichiarazione o definizione ambigua:
<sourcesyntaxhighlight lang="cpp">
class Timer {
public:
Riga 27 ⟶ 28:
return time_keeper.get_time();
}
</syntaxhighlight>
</source>
 
La riga
<sourcesyntaxhighlight lang="cpp">
TimeKeeper time_keeper(Timer());
</syntaxhighlight>
</source>
potrebbe essere interpretata come
# la definizione di una [[variabile (informatica)|variabile]] {{Code|time_keeper}} di classe {{Code|TimeKeeper}}, inizializzata con un'istanza anonima della classe {{Code|Timer}};
Riga 38 ⟶ 39:
 
Lo standard richiede di interpretare questa riga nella seconda maniera, per cui la riga successiva non sarà valida. Ad esempio, [[g++]] restituisce il seguente messaggio di errore:
<sourcesyntaxhighlight lang="console">
$ g++ -c time_keeper.cc
time_keeper.cc: In function ‘int main()’:
time_keeper.cc:15: error: request for member ‘get_time’ in ‘time_keeper’, which is
of non-class type ‘TimeKeeper(Timer (*)())’
</syntaxhighlight>
</source>
in quanto {{Code|time_keeper}} è una funzione dichiarata alla riga precedente, per cui non è possibile chiamare su essa il metodo {{Code|get_time()}}.
 
Riga 62 ⟶ 63:
 
Per fare in modo che l'istruzione venga interpretata come definizione di variabile con inizializzazione, è possibile aggiungere una coppia di parentesi supplementare:
<sourcesyntaxhighlight lang="cpp">
TimeKeeper time_keeper( (Timer()) );
</syntaxhighlight>
</source>
 
== Esempio con cast funzionale ==
Un altro esempio coinvolge l'uso del cast funzionale, quando viene usato per convertire il valore di un'espressione passata poi come variabile o come parametro di un costruttore
 
<sourcesyntaxhighlight lang="cpp">
void f(double adouble) {
int i(int(adouble));
}
</syntaxhighlight>
</source>
 
In questo caso, {{code|i}} viene interpretata come una definizione di funzione, equivalente alla seguente
 
<sourcesyntaxhighlight lang="cpp">
// takes an integer and returns an integer
int i(int adouble);
</syntaxhighlight>
</source>
 
Per [[Disambiguazione|disambiguare]] l'espressione affinché venga interpretata come dichiarazione di variabile, si può usare la stessa tecnica dell'esempio precedente, oppure si può sostituire il cast funzionale con un cast in stile C
 
<sourcesyntaxhighlight lang="cpp">
// declares a variable called 'i'
int i((int) adouble);
</syntaxhighlight>
</source>
 
oppure si può usare l'opportuno operatore di casting del C++
 
<sourcesyntaxhighlight lang="cpp">
// declares a variable called 'i'
int i(static_cast<int>(adouble));
</syntaxhighlight>
</source>
 
== Uniform initialization syntax ==
 
Lo standard [[C++11]] ha introdotto la ''uniform initialization syntax'' (sintassi di inizializzazione uniforme), che uniforma la sintassi per l'inizializzazione di oggetti o variabili con quella per gli [[array]] e permette di evitare ogni ambiguità con la dichiarazione di funzioni. La riga problematica del primo esempio può essere riscritta come:
 
<sourcesyntaxhighlight lang="cpp">
TimeKeeper time_keeper{Timer{}};
</syntaxhighlight>
</source>
 
== Note ==