plantillas - template typename t c++
¿Lanza un puntero a una plantilla para crear una instancia de esa plantilla? (2)
No es el elenco el que instancia la especialización de plantilla de clase, sino la llamada a función, porque el argumento desencadena ADL. La instanciación se realiza porque la integridad de la misma puede afectar la semántica del programa.
Ese clang no sigue la especificación que aquí se conoce y un mensaje de prensa fue enviado por mí hace algún tiempo. Ver http://llvm.org/bugs/show_bug.cgi?id=9440
static_cast<the_template<int>*>(0)
- ¿esto instancia la the_template
con tipo int
?
La razón para preguntar es el siguiente código, que generará un error al vincular el tiempo con una referencia indefinida a check_error<char>(void*, long)
con Clang y GCC 4.4.5, lo que indica que no crea una instancia de la plantilla. Sin embargo, MSVC y GCC 4.5.1 compilan y enlazan muy bien, lo que hace creer que crea una instancia de la plantilla. Sin embargo, si check_error<char>
el elenco, MSVC y GCC (tanto 4.4.5 como 4.5.1) tendrán errores en check_error<char>
solamente (el comportamiento deseado), mientras que Clang tendrá errores en ambas llamadas. Normalmente creo Clang cuando se trata de conformar cosas, pero me pregunto:
¿Qué compilador es correcto y qué dice el estándar al respecto?
#include <type_traits>
template<class T>
void check_error(void*, long);
template<class T>
struct foo{
template<class U>
friend typename std::enable_if<
std::is_same<T,U>::value
>::type check_error(foo<T>*, int){}
};
template struct foo<int>;
int main()
{
check_error<int>(static_cast<foo<int>*>(0), 0);
check_error<char>(static_cast<foo<char>*>(0), 0);
}
n3242 §14.7.1 / 1
A menos que una especialización de plantilla de clase haya sido explícitamente instanciada (14.7.2) o explícitamente especializada (14.7.3), la especialización de plantilla de clase se instanciará implícitamente cuando se haga referencia a la especialización en un contexto que requiera un tipo de objeto completamente definido o cuando la integridad del tipo de clase afecta la semántica del programa. La instanciación implícita de una especialización de plantilla de clase provoca la instanciación implícita de las declaraciones, pero no de las definiciones o argumentos predeterminados, de las funciones de miembros de clase, clases de miembros, miembros de datos estáticos y plantillas de miembros; y causa la instanciación implícita de las definiciones de uniones anónimas miembro. A menos que un miembro de una plantilla de clase o una plantilla de miembro haya sido explícitamente instanciado o explícitamente especializado, la especialización del miembro se instanciará implícitamente cuando se haga referencia a la especialización en un contexto que requiera que exista la definición de miembro; en particular, la inicialización (y cualquier efecto secundario asociado) de un miembro de datos estáticos no se produce a menos que el miembro de datos estáticos se use de una manera que requiera la definición del miembro de datos estáticos.
Me parece que static_cast
requeriría la static_cast
instancias de las declaraciones, pero no de las definiciones (ya que solo se trata de punteros).
n3242 §14.6.5 / 1
Las clases o funciones de amigo se pueden declarar dentro de una plantilla de clase. Cuando se crea una instancia de una plantilla, los nombres de sus amigos se tratan como si la especialización se hubiera declarado explícitamente en su punto de creación de instancias.
Creo que debería estar vinculado, pero tal vez alguien más pueda interpretar mejor que yo.