Por qué no se permite que la especialización parcial en un argumento que no es de tipo use parámetros de plantilla anidados


Tengo este código

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 usar la especialización parcial. Pero el compilador no aceptará esa especialización parcial, porque el Estándar requiere que rechace dicho código cuando un argumento no tipo de una especialización parcial hace referencia a un parámetro y no es simplemente un parámetro (como, A<N, N> sería válido). Pero ¿cuál es la razón de hacerlo?

Tenga en cuenta que simplemente puedo cambiar mi código a un más ejemplo wordy y es válido

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 ya no es un parámetro que no sea de tipo. Pero, ¿cuál es la razón por la que la especificación prohíbe la especialización parcial más directa?

Author: Johannes Schaub - litb, 2011-05-12

2 answers

Creo que mucho de esto es histórico. Los parámetros de plantilla que no son de tipo no estaban permitidos originalmente en absoluto. Cuando se añadieron, hubo lotes de limitaciones. A medida que la gente probaba diferentes posibilidades y confirmaba 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 trabajar alrededor de lo eliminarlos generalmente a menudo no causaría ninguna dificultad particular. Sobre todo se trata de una cuestión de si alguien se preocupó lo suficiente por este caso en particular para escribir un artículo sobre él.

 13
Author: Jerry Coffin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-05-12 20:52:49

La especialización parcial requiere que el argumento de la plantilla no-tipo sea resoluble 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 usando

A<25> a;

Pero también podrías tener

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

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

 -5
Author: Tom Wilson,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-05-12 16:45:41