C++ Modello Di Ambiguità
Domanda
Un amico e io stavamo discutendo dei template C++.Mi ha chiesto che cosa questo dovrebbe fare:
#include <iostream>
template <bool>
struct A {
A(bool) { std::cout << "bool\n"; }
A(void*) { std::cout << "void*\n"; }
};
int main() {
A<true> *d = 0;
const int b = 2;
const int c = 1;
new A< b > (c) > (d);
}
L'ultima riga principale dispone di due ragionevole analizza.'B' l'argomento del modello o è b > (c)
l'argomento del modello?
Anche se, è banale per la compilazione di questo, e vediamo cosa otteniamo, ci stavamo chiedendo cosa risolve l'ambiguità?
Soluzione
Per quanto ne so sarebbe compilato come new A<b>(c) > d
.Questo è l'unico modo ragionevole per analizzare IMHO.Se l'analizzatore non può assumere, in circostanze normali, un > fine di un modello argomento, che sarebbe risultato molto più ambiguità.Se si desidera che l'altro modo, si dovrebbe avere scritto:
new A<(b > c)>(d);
Altri suggerimenti
Come detto da Leon & Lee, 14.2/3 (C++ '03) definisce in modo esplicito questo comportamento.
C++ 0x aggiunge al divertimento con una regola simile per l'applicazione di >>
.Il concetto di base è che quando l'analisi di un modello-argomento-lista non nidificati >>
saranno trattati come due distinte >
>
i token e non lo shift di destra operatore:
template <bool>
struct A {
A(bool);
A(void*);
};
template <typename T>
class C
{
public:
C (int);
};
int main() {
A<true> *d = 0;
const int b = 2;
const int c = 1;
new C <A< b >> (c) > (d); // #1
new C <A< b > > (c) > (d); // #2
}
'#1 e#2' sono equivalenti in precedenza.
Questo, naturalmente, non risolve il fastidio di dover aggiungere spazi nidificata specializzazioni:
C<A<false>> c; // Parse error in C++ '98, '03 due to "right shift operator"
Il C++ standard definisce che, se per un modello di nome, seguito da una <
, il <
è sempre l'inizio di un modello di lista di argomenti e la prima non nidificata >
è considerato come la fine del modello di elenco di argomenti.
Se si vuole che il risultato della >
operatore di essere l'argomento del modello, quindi è necessario racchiudere l'espressione in parentesi.Non hai bisogno di parentesi se l'argomento è stato parte di un static_cast<>
o un altro modello di espressione.
L'avidità del lexer è probabilmente il fattore determinante in assenza di parentesi per rendere esplicito.Credo che il lexer non è avido.