2011-05-12 3 views
32

tengo este código¿Por qué es anulado por la especialización parcial en un argumento que no es el tipo de usar plantilla anidada parámetros

template<int N, bool C = true> 
struct A; 

template<int N> 
struct A<N, !(N % 5)> { 
    /* ... */ 
}; 

// should work 
A<25> a; 

Es decir, para los números N que son divisibles por 5, el compilador debe utilizar el parcial especialización. Pero el compilador no aceptará esa especialización parcial, porque el Estándar requiere que rechace dicho código cuando un argumento sin tipo de una especialización parcial haga referencia a un parámetro y no sea simplemente un parámetro (como, A<N, N> sería válido). Pero, ¿cuál es el motivo de hacerlo?

Tenga en cuenta que simplemente puedo cambiar el código para un ejemplo más prolijo y es válida

template<bool> struct wrap; 
template<int N, typename = wrap<true> > 
struct A; 

template<int N> 
struct A<N, wrap<!(N % 5)> > { 
    /* ... */ 
}; 

// should work 
A<25> a; 

Esto está bien porque no es un parámetro de tipo no más. ¿Pero cuál es la razón por la cual la especificación prohíbe la especialización parcial más directa?

+0

Incluso esto no está permitido: http://www.ideone.com/Vxx0R ... Me pregunto qué sección del estándar lo deshabilita. §14.5.4/9 se aplica aquí también? – Nawaz

+2

Esto es más o menos lo mismo que, ¿por qué no hay una especificación parcial de funciones cuando puedes simplemente envolverlas en una estructura? – Puppy

+1

¿Por qué incluso está usando plantillas con este código? –

Respuesta

12

Creo que mucho de esto es histórico. Los parámetros de plantilla sin tipo no se permitieron originalmente en absoluto. Cuando se agregaron, hubo lotes de limitaciones. Como las personas probaron diferentes posibilidades y confirmaron que no causaban problemas, se eliminaron algunas de las limitaciones.

Algunas de esas limitaciones originales permanecen sin ninguna razón en particular más allá del hecho de que nadie se molestó en trabajar para cambiarlas. Al igual que allí, muchos de ellos se pueden solucionar, por lo que su eliminación generalmente no causaría ninguna dificultad particular. En general, todo se reduce a la pregunta de si alguien se preocupó lo suficiente acerca de este caso particular como para escribir un artículo al respecto.

+2

¿Está permitido en C++ 11? – iammilind

-5

La especialización parcial requiere que el argumento de plantilla sin tipo se pueda resolver en tiempo de compilación.

En este punto

template<int N> 
struct A<N, !(N % 5)> { 
    /* ... */ 
}; 

N es una variable que puede tomar más de un valor y el compilador no puede calcular N % 5 con certeza.

Su ejemplo crea una instancia utilizando

A<25> a; 

pero también podría tener

A<25> a1; 
A<15> a2; 

¿Cómo el compilador elegir un valor para N en este escenario? No puede y tiene que rechazar el código.

+11

No sigo. Sabe 'N' porque estás diciendo lo que es. Es 25 o 15. – GManNickG

+0

El uso de la especialización parcial le dice al compilador que use una única instanciación específica para el segundo parámetro. Pero aquí A <25> y A <15> son tipos diferentes y, por lo tanto, habría más de una instanciación. –

+3

Lo siento, pero no entiendo lo que dices. Sí, 'A <25>' y 'A <15>' son tipos diferentes, ¿qué tiene eso que ver con la especialización? – GManNickG

Cuestiones relacionadas