2011-04-06 26 views
6

considerar:C++ ambigüedad sintaxis

void f(std::pair<bool,bool> terms = std::pair<bool,bool>(1,1)) {} 

gcc 4.4 está bien, gcc 4.3 se queja error: expected ',' or '...' before '>' token. La solución es:

void f(std::pair<bool,bool> terms = (std::pair<bool,bool>(1,1))) {} 

¿Cuál es el motivo? ¿Es un error en 4.3?

+0

Parece algo relacionado con el Pars más molesto (http://en.wikipedia.org/wiki/Most_vexing_parse). ¿Qué pasa con 'std :: pair terms = std :: make_pair (true, true)'? –

+1

¿por qué usar '1' para booleanos? No mezcle numerales y booleanos, realmente:/ –

Respuesta

8

Esto era un problema conocido. Cree que la segunda coma separa las declaraciones de parámetros. Esto se debe al hecho de que en una definición de clase, los argumentos predeterminados de la función primero se tokenizan y luego solo se analizan cuando se ha leído el cuerpo completo de la clase. Como en realidad no analiza el argumento predeterminado, no se da cuenta de que la coma es realmente una coma dentro de una lista de argumentos de plantilla.

Para obtener más información, contacte http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#325 sobre este producto. Cited

El otro problema es con la recopilación de los tokens que forman la expresión de argumento predeterminada. Los argumentos predeterminados que contienen ID de plantilla con más de un parámetro presentan una dificultad para determinar cuándo finaliza el argumento predeterminado. Considere,

template <int A, typename B> struct T { static int i;}; 
class C { 
    int Foo (int i = T<1, int>::i); 
}; 

El argumento predeterminado contiene una coma no entre paréntesis. ¿Se requiere que esta coma se vea como parte de la expresión de argumento predeterminada y no como el comienzo de otra declaración de argumento? Aceptar esto como parte del argumento predeterminado requeriría la búsqueda de nombre de T (para determinar que el '<' era parte de una lista de argumentos de plantilla y no un operador menor) antes de que se complete C. Además, cuanto más patológica

class D { 
    int Foo (int i = T<1, int>::i); 
    template <int A, typename B> struct T {static int i;}; 
}; 

sería muy difícil de aceptar. Aunque T se declara después de Foo, T está dentro del alcance dentro de la expresión de argumento predeterminada de Foo.

+4

C++ es difícil: O – Anycorn