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à?

È stato utile?

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.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top