tipos plantillas libreria funciones example ejemplo c++ templates grammar

libreria - tipos de plantillas en c++



Ambigüedad de la plantilla de C++ (4)

Según lo expresado por Leon & Lee, 14.2 / 3 (C ++ ''03) define explícitamente este comportamiento.

C ++ ''0x aumenta la diversión con una regla similar que se aplica a >> . El concepto básico es que al analizar una plantilla-argumento-lista, un >> no anidado se tratará como dos tokens distintos > y no como el operador de desplazamiento a la derecha:

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'' y ''# 2'' son equivalentes en lo anterior.

Por supuesto, esto soluciona esa molestia al tener que agregar espacios en especializaciones anidadas:

C<A<false>> c; // Parse error in C++ ''98, ''03 due to "right shift operator"

Un amigo y yo estábamos discutiendo las plantillas de C ++. Él me preguntó qué debería hacer esto:

#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); }

La última línea en main tiene dos análisis razonables. ¿Es ''b'' el argumento de la plantilla o es b > (c) el argumento de la plantilla?

Aunque, es trivial compilar esto, y ver lo que obtenemos, nos preguntábamos qué es lo que resuelve la ambigüedad.


AFAIK se compilaría como new A<b>(c) > d . Esta es la única forma razonable de analizarlo en mi humilde opinión. Si el analizador no puede asumir bajo circunstancias normales a> finalizar un argumento de plantilla, eso generaría mucha más ambigüedad. Si lo quiere de otra manera, debería haber escrito:

new A<(b > c)>(d);


La codicia del lexer es probablemente el factor determinante en ausencia de paréntesis para hacerlo explícito. Supongo que el lexer no es codicioso.


El estándar de C ++ define que si para un nombre de plantilla seguido de un < , el < es siempre el principio de la lista de argumentos de la plantilla y el primero no anidado > se toma como el final de la lista de argumentos de la plantilla.

Si tu intención era que el resultado del operador > fuera el argumento de la plantilla, entonces necesitarías encerrar la expresión entre paréntesis. No necesita paréntesis si el argumento era parte de una static_cast<> u otra expresión de plantilla.