Al crear un pequeño programa de ejemplo con Microsoft VisualStudio 2008 noté algo extraño sobre la deducción de tipos pasados a las plantillas. Considere este ejemplo:¿Por qué se eliminan los calificadores de los argumentos de la plantilla al deducir el tipo?
template<class T>
void f(T v) {
x; // trigger a compile error
(void)v;
}
template<class T>
void g(T v) {
f(v);
}
void h() {
int i;
g<const int &>(i);
}
Compilar este ejemplo utilizando cl /c foo.cpp
produce un error de compilación (como se pretende). Lo que es interesante es el valor del parámetro de la plantilla 'T'. Esto es lo que VisualStudio 2008 impresiones:
mini.cpp(3) : error C2065: 'x' : undeclared identifier
mini.cpp(9) : see reference to function template instantiation 'void f<int>(T)' being compiled
with
[
T=int
]
mini.cpp(14) : see reference to function template instantiation 'void g<const int&>(T)' being compiled
with
[
T=const int &
]
Nótese cómo en g
, el tipo del argumento es const int &
pero en f
es sólo int
. Aparentemente, la parte de referencia a resistencia se eliminó al deducir el tipo que se usaría al crear la plantilla f
. Al ajustar el ejemplo de modo que f
se invoca como
f<T>(v);
el tipo es const int &
tanto en f
y g
. ¿Porqué es eso? ¿Es este comportamiento específico? Confié en secreto en el tipo de argumento de la función v
que se pasará al f
, pero aparentemente no es así.
'C++' Plantillas + MSVC++ = Mala combinación. –
@Prasoon: GCC deduce el mismo tipo.Por supuesto, en GCC, el código del que pregunta desencadena un error de compilación en 'f' de la plantilla, antes de que se acerque a pensar en instanciarlo, porque GCC hace la compilación en dos fases correctamente. 'x' no depende de un parámetro de plantilla, por lo que debe rechazarse en la primera fase (como en GCC), no en la segunda (como en MSVC). Pero cambie 'x' a' v = 1; ', y se ve fácilmente que GCC no crea instancias de' f' con 'const int &' a menos que especifique 'f (v)' en 'g' explícitamente. –