2010-10-14 26 views
13

Mientras lee this, estoy confundido por los siguientes ejemplos:función de plantilla especialización

// Example 2: Explicit specialization 
// 
template<class T> // (a) a base template 
void f(T); 

template<class T> // (b) a second base template, overloads (a) 
void f(T*);  //  (function templates can't be partially 
        //  specialized; they overload instead) 

template<>  // (c) explicit specialization of (b) 
void f<>(int*); 

// ... 

int *p; 
f(p);   // calls (c) 

Aquí, (c) es una especialización explícita de (b).

// Example 3: The Dimov/Abrahams Example 
// 
template<class T> // (a) same old base template as before 
void f(T); 

template<>  // (c) explicit specialization, this time of (a) 
void f<>(int*); 

template<class T> // (b) a second base template, overloads (a) 
void f(T*); 

// ... 

int *p; 
f(p);   // calls (b)! overload resolution ignores 
        // specializations and operates on the base 
        // function templates only 

Aquí (c) es una especialización explícita de (a). ¿Porqué es eso? ¿Esto es por el orden de la declaración?

+1

Offhand Solo diría "sí", y suponiendo que el código sea válido, esa es la única respuesta posible. Pero la pregunta es si el segundo código es válido. Creo que es válido, pero encontrar esto en el estándar podría ser mucho trabajo ... –

+0

@Alf P. Steinbach: ¿por qué el segundo código no podría ser válido? – Donotalo

+0

@Donato: sin tener en cuenta los autores (que Really (TM) conocen sus cosas en lo que respecta a las plantillas), solo desconfío del código que tiene un efecto dependiente del orden u otro efecto más "arbitrario". El estándar está diseñado para proteger contra tales cosas, por ejemplo, la compilación en dos fases de las plantillas protege contra ese tipo de cosas. Entonces solo tengo un <0.5% siente que puede haber alguna regla al respecto, y posiblemente una que no requiera ningún diagnóstico. –

Respuesta

11

Sí, es por el orden de la declaración. Cuando el compilador encuentra (c) en el segundo conjunto, la única plantilla definida para especializarse es (a).

Es por esto que debe tener cuidado al ordenar las especializaciones de su plantilla.

El lenguaje de programación C++ entra en bastante detalle sobre esto (Sección 13.5.1). Lo recomiendo altamente.

10

Es el pedido pero no es solo el pedido. Para el primer código, ambas plantillas se definieron anteriormente. Pero el segundo fue tomado.

Esto se debe a que las dos plantillas se comparan y se encuentra que (T) coincide con cualquier tipo que (T*) partidos, sino que (T*) no coincide con todos los tipos que (T) los partidos. Por lo tanto, la segunda plantilla es más especializada. Cuando coloca una especialización explícita y esas dos plantillas coinciden, las plantillas se comparan y la más especializada se asocia con la especialización explícita. Esta comparación se llama "ordenamiento parcial".

8

El estándar tiene que decir lo siguiente sobre el posicionamiento relativo de las declaraciones de especialización explícitas. [Sección 14.7.3]

El colocación de declaraciones especialización explícita para las plantillas de de función, plantillas de clase, funciones miembro de plantillas de clase, miembros de datos estáticos de plantillas de clase, clases de miembros de plantillas de clase, plantillas de clase de miembro de plantillas de clase , plantillas de funciones miembro de plantillas de clase, funciones miembro de plantillas miembro de plantillas de clase, funciones miembro de plantillas miembro de clases no plantilla, plantillas de función miembro de clases miembro de plantillas de clase, etc., y la colocación de declaraciones de especialización parcial de plantillas de clase, plantillas de clase de miembro de clases que no son de plantilla, plantillas de clase de miembro de plantillas de clase, etc., puede afectar si un programa está bien formado de acuerdo con la posición relativa de las declaraciones de especialización explícita y sus puntos de creación de instancias en la unidad de traducción como se especifica arriba y debajo de. Al escribir una especialización, tenga cuidado con su ubicación; o para hacer que compile será una prueba que encienda su autoinmolación.

+1

+1 por ** auto-inmolación ** - suficiente para ahuyentar a los neófitos que buscan aprender C++ – kfmfe04

Cuestiones relacionadas