2012-07-27 4 views
10

El siguiente fragmento de código se compila en gcc-4.7.1:¿Puede funcionar el parámetro de la plantilla predeterminada antes de los no predeterminados?

struct X {}; 

template <class T = X, typename U> 
void f(const U& m) { 
} 


int main() { 
    f<>(0); 
} 

Sin embargo, éste no lo hace:

struct X {}; 

template <class T = X, typename U> 
void f(const U& m) { 
    auto g = []() {}; 
} 


int main() { 
    f<>(0); 
} 

gcc-4.7.1 se queja:

c.cpp: In function 'void f(const U&)': 
c.cpp:5:15: error: no default argument for 'U' 

Entonces mi pregunta es: ¿está poniendo los parámetros por defecto antes de que los parámetros no predeterminados se corrijan en la plantilla de función? Si es así, ¿por qué no compila el segundo? Si no, ¿por qué compila el primero? ¿Qué dice el estándar C++ 11 sobre esta sintaxis?

+0

http://stackoverflow.com/questions/2447458/default-template-arguments-for-function-templates – Andrew

+0

@Andrew, la publicación que ha proporcionado es demasiado larga. ¿Puede indicar qué respuesta dice acerca de si es correcto colocar el parámetro predeterminado antes que los no predeterminados? –

+1

@icando: no hay nada en el estándar que * prohíba * poner argumentos de plantilla predeterminados para plantillas de funciones en cualquier lugar. Solo las plantillas * class * están restringidas. –

Respuesta

11

Está explícitamente prohibido para clases y alias. n3290 § 14.1.11 estados:

Si una plantilla de parámetros de una plantilla de plantilla de clase o alias tiene una plantilla-argumento por defecto, cada subsecuente plantilla de parámetros habrá de tener una plantilla-argumento predeterminado suministrado o sea una parámetro de plantilla paquete

para las funciones de la única restricción parece estar relacionado a los paquetes de parámetros:

un paquete de parámetro de plantilla de una plantilla de función no serán seguido de otro parámetro de plantilla a menos que el parámetro de plantilla se puede deducir o tiene un defecto argumento

Pero está claro que no se refiere a este caso.

Dado que nada en el § 14 lo prohíbe para las funciones, parece que tenemos que asumir que está permitido.

A note from a working group reports parece confirmar que esta es la intención. La redacción propuesta original de esa sección es:

Si un parámetro de plantilla de una plantilla de clase tiene un argumento de plantilla predeterminado, todos los parámetros de plantilla subsiguientes tendrán un argumento de plantilla predeterminado. [Nota: Esto no es un requisito para las plantillas de función porque argumentos de plantilla podrían ser deducidas (14.8.2 [temp.deduct]).]

no puedo ver donde esa nota fue en la versión final aunque.

+1

así que está permitido, y el error del compilador es solo un error de gcc? –

+0

I * think * está permitido. Si no se supone que es un defecto en el estándar, no hay palabras que lo rechacen.el sonido en mi sistema también falla al compilarlo, por lo que es problemático para los compiladores en este momento. – Flexo

+1

el clang-3.2 en mis MacPorts realmente lo compila. ¿Entonces tal vez clang arregló eso ya? –

Cuestiones relacionadas