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.