He encontrado un verdadero quemahojas en C++, nunca me había sucedido antes.La función de plantilla de C++ obtiene valores predeterminados erróneos
La esencia del problema es que al invocar mi función (plantilla), los argumentos que he definido por defecto tienen sus valores codificados. Solo ocurre si llamo a la función con los valores predeterminados.
Mi función de plantilla se declara así:
template <typename T>
vector2<T> transform(vector2<T> const &vec, matrix4<T> const &m, T z = T(0), T w = T(1));
Está más tarde, en la misma cabecera, define así:
template <typename T>
inline vector2<T> transform(vector2<T> const &vec, matrix4<T> const &m, T z, T w)
{
vector4<T> res = m * vector4<T>(vec.x, vec.y, z, w);
return vector2<T>(res.x, res.y);
}
Ahora cuando llamo a esto con los valores predeterminados (transform(vector2<double>(0, 1), view_transform)
) I no obtengo los valores que espero Entrando en transform
con el depurador de VC++ veo z
y w
teniendo valores "divertidos" (que en mi experiencia significa que algo no se inicializa correctamente). Los valores divertidas
ejemplo sería: 0.0078125000000000000 y 2.104431116947e-317 # DEN
Ahora he intentado encontrar la respuesta en C++ FAQ Lite, googling; incluso traté de calmarme con Schubert, pero no puedo por la vida de mí resolverlo. Supongo que es muy simple y sospecho que es una especie de tontería de plantilla en el trabajo.
¿Hay alguna manera de obtener los valores predeterminados que espero y deseo, y por qué me hace esto?
Edición 1:
Si la llamada cambio por lo que utiliza flotadores lugar (transform(vector2<float>(0, 1), view_transform)
) el problema desaparece. Parece que esto solo ocurre si T
= double
.
Edición 2:
Esto sólo ocurre si tengo dos especializaciones double
y float
. Si utilizo una especialización de flotación en un lugar, la doble especialización obtiene valores predeterminados extraños. Si cambio todos los lugares, se llama a la función para que use el doble de "desaparece". Todavía no entiendo por qué, sin embargo, es como si utilizara compensaciones defectuosas o algo al configurar z
y w
.
Datos 3:
Tales from the C++ Cripta:
#include <sgt/matrix4.hpp>
int main(int argc, char *argv[])
{
sgt::matrix4<double> m0(
2, 0, 0, 1,
0, 2, 0, 1,
0, 0, 1, 0,
0, 0, 0, 1);
m0 *= m0;
sgt::vector2<double> blah0 = sgt::transform(sgt::vector2<double>(1, 0), m0);
sgt::matrix4<float> m1(
2, 0, 0, 1,
0, 2, 0, 1,
0, 0, 1, 0,
0, 0, 0, 1);
m1 *= m1;
sgt::vector2<float> blah1 = sgt::transform(sgt::vector2<float>(1, 0), m1);
printf("%f", blah0.x);
printf("%f", blah1.x);
}
En matrix4.hpp:
// ...
template <typename T>
vector2<T> transform(vector2<T> const &vec, matrix4<T> const &m, T z = T(0), T w = T(1));
template <typename T>
inline vector2<T> transform(vector2<T> const &vec, matrix4<T> const &m, T z, T w)
{
vector4<T> res = m * vector4<T>(vec.x, vec.y, z, w);
return vector2<T>(res.x, res.y);
}
// ...
Si me quedo eso, la doble especialización tiene su defecto argumentos correctos, pero la versión flotante obtiene ambos argumentos por defecto como cero (0.000000) que aunque mejor, todavía no es z = 0
y w = 1
.
Editar 4:
hizo un Connect issue.
No veo nada malo con eso ... ¿Podría probarlo con un compilador diferente? –
¿Qué compilador estás usando y en qué plataforma estás? – Alerty
Ah, perdón, olvidé esa información, Microsoft VC++ 10 (16.00.30319.01). @j_random_hacker: Hmm, bueno, podría descargar MinGW e intentarlo. – Skurmedel