C ++ 11 static_assert y ejemplificación de plantilla

En C ++ 11, ¿la operación de static_assert dentro de una plantilla depende de si esa plantilla ha sido instanciada o no? Por ejemplo, con el siguiente código

template  void sa() { static_assert(0,"Hello."); } int main(int argc, char *argv[]) { return 0; } 

GCC 4.5.0 fallará la aserción y producirá el “Hola”. mensaje. El comstackdor digital Mars versión 8.42n, por otro lado, no da ningún mensaje.

GCC es correcto y el otro comstackdor también es correcto. Consulte 14.6p8 en la especificación

Si no se puede generar una especialización válida para una definición de plantilla, y esa plantilla no se crea una instancia, la definición de plantilla está mal formada, no se requiere diagnóstico.

Por lo tanto, un comstackdor es libre de rechazar el siguiente

 template void f() { static_assert(0, "may trigger immediately!"); static_assert(sizeof(T) == 0, "may trigger immediately!"); } 

Si quiere ir a salvo, debe organizarlo para que el comstackdor no pueda saber hasta la instanciación si la expresión booleana será verdadera o falsa. Por ejemplo, obtenga el valor de getvalue::value , con getvalue como una plantilla de clase (podría especializarse, por lo que el comstackdor ya no puede conocer el valor booleano).

Creo que el comstackdor está en su derecho de expandir cualquier aserción estática que no dependa de los parámetros de la plantilla sin la necesidad de una instanciación, pero no creo que esto sea necesario. Recuerde también que los diferentes borradores de Estándares pueden tener diferentes reglas sobre cuándo esto puede ocurrir.

El borrador de C ++ 0x ( N3242 ) dice en 14.6p8:

“Si no se puede generar una especialización válida para una definición de plantilla, y esa plantilla no se crea una instancia, la definición de plantilla está mal formada, no se requiere diagnóstico”.

Las mismas palabras aparecen en el estándar C ++ 03.

En el caso del ejemplo de la pregunta, no se puede crear una instancia válida para esta plantilla, por lo que se aplica la fraseología citada.

Como no se requiere diagnóstico, el comstackdor puede comstackr el progtwig si la plantilla no se crea una instancia. Por supuesto, si se crea una instancia, entonces el progtwig está mal formado, con un diagnóstico requerido.

Usé una función auxiliar para hacer que el falso dependiera del parámetro de la plantilla:

 template bool dependentFalse() { return false; } template Foo foo() { static_assert(dependentFalse(), "this template shouldn't be instantiated"); } 

Esta es la sección 14.6.2 en C ++ estándar.

Su static_assert está relacionado con el soporte de nombres no dependientes vinculantes cuando se analiza inicialmente una plantilla . El Comstackdor de Marte Digital actualmente no es compatible con los nombres obligatorios no dependientes. GCC 4.5.0 admite nombres vinculantes no dependientes.

Si su expresión no depende de los parámetros de la plantilla, entonces se conoce dicha expresión cuando se analiza inicialmente una plantilla. El comstackdor debe mostrar el mensaje de error. GCC 4.5.0 lo hace.

Reemplace su 0 en static_assert con I*I < 0 , para la expansión y obtendrá el nombre dependiente. Aparecerá un mensaje de error solo para el caso de la plantilla desinstalada.

Este progtwig genera un error:

 template  void sa() { static_assert(0,"Hello."); } template <> void sa<0>() { } int main(int argc, char *argv[]) { return 0; } 

Este progtwig no:

 template  void sa() { static_assert(I != 0,"Hello."); } template <> void sa<0>() { } int main(int argc, char *argv[]) { return 0; } 

No tiene ningún sentido que este sea el caso. Así que llegué a la conclusión de que g ++ 4.5 debe estar en error si está activando el static_assert en una plantilla static_assert .

Y aún más problemático, el siguiente progtwig imprime I == 1 .

 #include  using ::std::cout; template  void sa() { cout << "I == " << I << '\n'; static_assert(I != 0,"Hello."); } template <> void sa<0>() { cout << "I == " << 0 << '\n'; } int main(int argc, char *argv[]) { sa<1>(); return 0; } 

Esto indica que hay un error grave con la forma en que gcc maneja static_assert .

Editar : Oh, bueno. Mi progtwig tiene un error. Debería leer I == 0 , no I != 0 , y si eso ha cambiado, no comstack como debería hacerlo.