Ho colpito un vero capocannoniere in C++, non mi è mai successo prima.La funzione modello C++ ottiene valori predefiniti errati
Il nocciolo del problema è che dopo l'invocazione della mia funzione (modello) gli argomenti per i quali sono stati definiti i valori predefiniti hanno i loro valori codificati. Succede solo se chiamo la funzione con i valori predefiniti.
La mia funzione template è dichiarato così:
template <typename T>
vector2<T> transform(vector2<T> const &vec, matrix4<T> const &m, T z = T(0), T w = T(1));
E 'più tardi, nella stessa intestazione, definita in questo modo:
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);
}
Ora, quando io chiamo questo con valori di default (transform(vector2<double>(0, 1), view_transform)
) I non ottenere i valori che mi aspetto Entrando in transform
con il debugger di VC++ vedo z
e w
con valori "divertenti" (che nella mia esperienza significa che qualcosa non è inizializzato correttamente).
Esempio valori divertenti sarebbero: ,0078125000000000000 e 2.104431116947e-317 # DEN
Ora ho provato a trovare la risposta su C++ FAQ Lite, googling; ho anche provato a calmarmi con Schubert, ma non posso per la vita di me capirlo. Immagino che sia molto semplice e sospetto che si tratti di una sorta di mascherata da imbroglione al lavoro.
C'è un modo per ottenere i valori predefiniti che mi aspetto e voglio, e perché mi fa questo?
Edit 1:
Se la chiamata cambiamento in modo che utilizza i galleggianti invece (transform(vector2<float>(0, 1), view_transform)
) il problema va via. Sembra che ciò accada solo se T
= double
.
Edit 2:
succede solo se ho due specializzazioni per double
e float
. Se uso una specializzazione flottante in un punto, la specializzazione doppia ottiene valori predefiniti strani. Se cambio tutti i punti in cui viene chiamata la funzione, quindi usa il doppio, i problemi "vanno via". Non riesco ancora a capire perché, però, è come utilizzare offset difettosi o qualcosa del genere durante la configurazione di z
e w
.
Edit 3:
Racconti dalla 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);
}
In 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);
}
// ...
se corro questo, il doppio di specializzazione ha il difetto argomenti corretti, ma la versione float ottiene sia gli argomenti predefiniti come zero (0.000000) che, anche se meglio, non è ancora z = 0
e w = 1
.
Edit 4:
fatto un Connect issue.
Non riesco a vedere niente di sbagliato ... Potrebbe provare con un compilatore diverso? –
Che compilatore stai usando e su quale piattaforma sei? – Alerty
Ah scusa, ho dimenticato questa informazione, Microsoft VC++ 10 (16.00.30319.01). @j_random_hacker: Hmm, beh, potrei scaricare MinGW e provare. – Skurmedel