Problèmes de compilation avec des classes templates

Signaler
Messages postés
7
Date d'inscription
dimanche 2 février 2003
Statut
Membre
Dernière intervention
7 mai 2008
-
Messages postés
7
Date d'inscription
dimanche 2 février 2003
Statut
Membre
Dernière intervention
7 mai 2008
-
Pour une raison qui m'échappe, mon compilateur(GCC sous Dev-cpp) me renvoie l'erreur suivante:

[b]
In file included from Vector3D.hpp:6,
                 from main.cpp:3:
Matrix3D.hpp:29: error: ISO C++ forbids declaration of `Vector3D' with no type
Matrix3D.hpp:29: error: expected `;' before '<' token
Matrix3D.hpp:71: error: expected constructor, destructor, or type conversion before '<' token

Matrix3D.hpp:71: error: expected `;' before '<' token

make.exe: *** [main.o] Error 1

Execution terminated"
/b

J'ai essayé de recompiler mes classes en me débarassant du caractère template(class Vector3D en lieu et place de Vector3D<T>,et float à la place de T) et j'ai le même problème.

8 réponses

Messages postés
7
Date d'inscription
dimanche 2 février 2003
Statut
Membre
Dernière intervention
7 mai 2008

Voici le contenu de l'entête Vector3D.hpp:

#ifndef VECTOR3D_HPP
#define VECTOR3D_HPP

#include
#include
#include "Matrix3D.hpp"

using namespace std;

template<class T>
class Vector3D
{
public:
T x;
T y;
T z;

Vector3D();
Vector3D( T _x , T _y , T _z );
Vector3D( const Vector3D<T>& v );
~Vector3D();

T operator*( const Vector3D<T>& v )const;
Vector3D operator*( const T a )const;
//Matrix3D<T> operator*( const Matrix3D<T>& )const;
Vector3D operator+( const Vector3D<T>& v )const;
Vector3D operator-( const Vector3D<T>& v )const;
Vector3D operator/( const T a )const;
Vector3D& operator+=( const Vector3D<T>& v );
Vector3D& operator-=( const Vector3D<T>& v );
Vector3D& operator*=( const Vector3D<T>& v );
bool operator!=( const Vector3D<T>& v )const;
bool operator==( const Vector3D<T>& v )const;

Vector3D opposite()const;
T squaredLength()const;
void print()const;
//Matrix3D<T> star()const;

template <class U> friend ostream& operator<<( ostream& , const Vector3D& );
template <class U> friend istream& operator>>( istream& , Vector3D& );

};

template<class T>
Vector3D<T>::Vector3D()
{
x = 0;
y = 0;
z = 0;
}

template<class T>
Vector3D<T>::Vector3D( T _x , T _y , T _z )
{
x = _x;
y = _y;
z = _z;
}

template<class T>
Vector3D<T>::Vector3D( const Vector3D<T>& v )
{
x = v.x;
y = v.y;
z = v.z;
}

template<class T>
Vector3D<T>::~Vector3D(){}

template<class T>
T Vector3D<T>::operator*( const Vector3D<T>& v )const
{
return ( x * v.x + y * v.y + z * v.z );
}

template<class T>
Vector3D<T> Vector3D<T>::operator*( const T a )const
{
return Vector3D<T>( x * a , y * a , z * a );
}

//template<class T>
//Matrix3D<T> Vector3D<T>::operator*( const Matrix3D<T>& )const
//{
// return Matrix3D<T>();
//}

template<class T>
Vector3D<T> Vector3D<T>::operator/( const T a )const
{
return Vector3D<T>( x / a , y / a , z / a );
}

template<class T>
Vector3D<T> Vector3D<T>::operator+( const Vector3D<T>& v )const
{
return Vector3D<T>( x + v.x , y + v.y , z + v.z );
}

template<class T>
Vector3D<T> Vector3D<T>::operator-( const Vector3D<T>& v )const
{
return Vector3D<T>( x - v.x , y - v.y , z - v.z );
}

template<class T>
Vector3D<T>& Vector3D<T>::operator+=( const Vector3D<T>& v )
{
x += v.x;
y += v.y;
z += v.z;
}

template<class T>
Vector3D<T>& Vector3D<T>::operator-=( const Vector3D<T>& v )
{
x -= v.x ;
y -= v.y ;
z -= v.z;
}

template<class T>
Vector3D<T>& Vector3D<T>::operator*=( const Vector3D<T>& v )
{
x *= v.x;
y *= v.y;
z *= v.z;
}

template<class T>
T Vector3D<T>::squaredLength()const
{
return ( x * x + y * y + z * z );
}

template<class T>
bool Vector3D<T>::operator!=( const Vector3D<T>& v )const
{
return ( fabs( x - v.x ) > 1.0e-6 && fabs( y - v.y ) > 1.0e-6 && fabs( z - v.z ) > 1.0e-6 );
}

template<class T>
bool Vector3D<T>::operator==( const Vector3D<T>& v )const
{
return ( fabs( x - v.x ) <= 1.0e-6 && fabs( y - v.y ) <= 1.0e-6 && fabs( z - v.z ) <= 1.0e-6 );
}

template<class T>
Vector3D<T> Vector3D<T>::opposite()const
{
return Vector3D<T>( -x , -y , -z );
}

template<class T>
void Vector3D<T>::print()const
{
cout << "(" << setiosflags( ios::right | ios::fixed | ios::showpoint ) << setprecision( 3 ) << x;
cout << "," << setiosflags( ios::right | ios::fixed | ios::showpoint ) << setw( 6 ) << setprecision( 3 ) << y;
cout << "," << setiosflags( ios::right | ios::fixed | ios::showpoint ) << setw( 6 ) << setprecision( 3 ) << z;
cout << ")";
}

template<class T>
ostream& operator<<( ostream& out , const Vector3D<T>& v )
{
out << "(" << setiosflags( ios::right | ios::fixed | ios::showpoint ) << setprecision( 3 ) << v.x;
out << "," << setiosflags( ios::right | ios::fixed | ios::showpoint ) << setw( 6 ) << setprecision( 3 ) << v.y;
out << "," << setiosflags( ios::right | ios::fixed | ios::showpoint ) << setw( 6 ) << setprecision( 3 ) << v.z;
out << ")";
}

template<class T>
istream& operator>>( istream& in , Vector3D<T>& v )
{
cout << "Enter x : ";
in >> v.x;
cout << "Enter y : ";
in >> v.y;
cout << "Enter z : ";
in >> v.z;
}

template<class T>
Vector3D<T> crossProduct( const Vector3D<T>& v1 , const Vector3D<T>& v2 )
{
return Vector3D<T>( v1.y * v2.z - v2.y * v1.z ,
v2.x * v1.z - v1.x * v2.z ,
v1.x * v2.y - v2.x * v1.y );
}

#endif


Et le contenu de la classe Matrix3D.hpp

#ifndef MATRIX3D_HPP
#define MATRIX3D_HPP

#include "Vector3D.hpp"
#include
#include <cmath>
#include <cassert>

using namespace std;

template<class T>
class Matrix3D
{
public:
T a_11;
T a_12;
T a_13;
T a_21;
T a_22;
T a_23;
T a_31;
T a_32;
T a_33;

Matrix3D();
Matrix3D( T angle );
Matrix3D( T a, T b, T c, T d , T e, T f, T g, T h, T i );

Vector3D<T> operator*( const Vector3D<T>& v )const;
Matrix3D operator*( const Matrix3D<T>& m )const;
Matrix3D inverse()const;
Matrix3D transpose()const;

template <class U> friend ostream& operator<<( ostream& , const Matrix3D& );
template <class U> friend istream& operator>>( istream& , Matrix3D& );
};

template<class T>
Matrix3D<T>::Matrix3D()
{
a_11 = 0;
a_12 = 0;
a_13 = 0;
a_21 = 0;
a_22 = 0;
a_23 = 0;
a_31 = 0;
a_32 = 0;
a_33 = 0;
}

template<class T>
Matrix3D<T>::Matrix3D( T a, T b, T c, T d , T e, T f, T g, T h, T i )
: a_11(a) , a_12(b) , a_13(c) , a_21(d) , a_22(e) , a_23(f) , a_31(g) , a_32(h) , a_33(i){}

template<class T>
Matrix3D<T>::Matrix3D( T angle )
{
a_11 = cos(angle);
a_12 = sin(angle);
a_13 = 0;
a_21 = -a_12;
a_22 = a_11;
a_23 = 0;
a_31 = 0;
a_32 = 0;
a_33 = 1;
}

template<class T>
Vector3D<T> Matrix3D<T>::operator*( const Vector3D<T>& v )const
{
return Vector3D<T>( a_11 * v.x + a_12 * v.y + a_13 * v.z,
a_21 * v.x + a_22 * v.y + a_23 * v.z,
a_31 * v.x + a_32 * v.y + a_33 * v.z );
}

template<class T>
Matrix3D<T> Matrix3D<T>::operator*( const Matrix3D<T>& m )const
{
return Matrix3D<T>( a_11 * m.a_11 + a_12 * m.a_21 + a_13 * m.a_31 ,
a_11 * m.a_12 + a_12 * m.a_22 + a_13 * m.a_32 ,
a_11 * m.a_13 + a_12 * m.a_23 + a_13 * m.a_33 ,
a_21 * m.a_11 + a_22 * m.a_21 + a_23 * m.a_31 ,
a_21 * m.a_12 + a_22 * m.a_22 + a_23 * m.a_32 ,
a_21 * m.a_13 + a_22 * m.a_23 + a_23 * m.a_33 ,
a_31 * m.a_11 + a_32 * m.a_21 + a_33 * m.a_31 ,
a_31 * m.a_12 + a_32 * m.a_22 + a_33 * m.a_32 ,
a_31 * m.a_13 + a_32 * m.a_23 + a_33 * m.a_33);
}

template<class T>
Matrix3D<T> Matrix3D<T>::inverse()const
{
T c_11 = ( a_22 * a_33 - a_23 * a_32 );
T c_12 = ( a_21 * a_33 - a_23 * a_31 );
T c_13 = ( a_21 * a_32 - a_22 * a_31 );
T c_21 = ( a_12 * a_33 - a_13 * a_32 );
T c_22 = ( a_11 * a_33 - a_13 * a_31 );
T c_23 = ( a_11 * a_32 - a_12 * a_31 );
T c_31 = ( a_12 * a_23 - a_13 * a_22 );
T c_32 = ( a_11 * a_23 - a_13 * a_21 );
T c_33 = ( a_11 * a_22 - a_12 * a_21 );

T det = a_11 * c_11 - a_12 * c_12 + a_13 * c_13;

//cout << "det = " << det << endl;

assert( abs(det) > 1.0e-10 );

c_11 /= det;
c_12 /= -1*det;
c_13 /= det;
c_21 /= -1*det;
c_22 /= det;
c_23 /= -1*det;
c_31 /= det;
c_32 /= -1*det;
c_33 /= det;

return Matrix3D( c_11 , c_21 , c_31 , c_12 , c_22 , c_32 , c_13 , c_23 , c_33 );
}

template<class T>
Matrix3D<T> Matrix3D<T>::transpose()const
{
return Matrix3D<T>( a_11 , a_21 , a_31 ,
a_12 , a_22 , a_32 ,
a_13 , a_23 , a_33 );
}

template <class T>
ostream& operator<<( ostream& out , const Matrix3D<T>& m )
{
cout << setiosflags( ios::right | ios::fixed | ios::showpoint ) << setw( 10 ) << setprecision( 4 ) << m.a_11;
cout << setiosflags( ios::right | ios::fixed | ios::showpoint ) << setw( 10 ) << setprecision( 4 ) << m.a_12;
cout << setiosflags( ios::right | ios::fixed | ios::showpoint ) << setw( 10 ) << setprecision( 4 ) << m.a_13 << endl;
cout << setiosflags( ios::right | ios::fixed | ios::showpoint ) << setw( 10 ) << setprecision( 4 ) << m.a_21;
cout << setiosflags( ios::right | ios::fixed | ios::showpoint ) << setw( 10 ) << setprecision( 4 ) << m.a_22;
cout << setiosflags( ios::right | ios::fixed | ios::showpoint ) << setw( 10 ) << setprecision( 4 ) << m.a_23 << endl;
cout << setiosflags( ios::right | ios::fixed | ios::showpoint ) << setw( 10 ) << setprecision( 4 ) << m.a_31;
cout << setiosflags( ios::right | ios::fixed | ios::showpoint ) << setw( 10 ) << setprecision( 4 ) << m.a_32;
cout << setiosflags( ios::right | ios::fixed | ios::showpoint ) << setw( 10 ) << setprecision( 4 ) << m.a_33 << endl;
}

template <class T>
istream& operator>>( istream& in , Matrix3D<T>& m )
{
cout << "Enter a_11 : ";
cin >> m.a_11;
cout << "Enter a_12 : ";
cin >> m.a_12;
cout << "Enter a_13 : ";
cin >> m.a_13;

cout << "Enter a_21 : ";
cin >> m.a_21;
cout << "Enter a_22 : ";
cin >> m.a_22;
cout << "Enter a_23 : ";
cin >> m.a_23;

cout << "Enter a_31 : ";
cin >> m.a_31;
cout << "Enter a_32 : ";
cin >> m.a_32;
cout << "Enter a_33 : ";
cin >> m.a_33;
}

#endif

Et pour finir le main:

#include
#include <math.h>
#include "Vector3D.hpp"
#include "Vehicle2D.hpp"
#include "Matrix3D.hpp"
#include "Quaternion.hpp"

using namespace std;

const float pi = 3.14159265;

int main()
{
cout << "Test program" << endl;

// Vector3D<float> v1(cos(pi/3),sin(pi/3),0);
Vector3D<float> v1(0,0,1);
cout << "v1 = " << v1 << endl;

Vector3D<float> v2(cos(-pi/3),sin(-pi/3),0);
cout << "v2 = " << v2 << endl;

Vector3D<float> v3(cos(-pi/4),sin(-pi/4),0);
cout << "v3 = " << v3 << endl;

cout << "v2 * v2 = " << v2 * v2 << endl;

// cout << "fabs(-.07897) = " << fabs(-.07897) << endl;
// cout << "(v2==v2)=" << (v2==v2) << endl;
//
// cout << "crossProduct(v1,v2) = " << crossProduct(v1,v2) << endl;

// Vehicle2D<float> veh;
// cin >> veh;
// cout << veh;
// float dt = 0.25;
// veh.update( dt );
// cout << veh;

// Matrix3D<float> m(cos(pi/3),sin(pi/3),0,-sin(pi/3),cos(pi/3),0,0,0,1);
// cout << "m = " << endl << m << endl;
//
// Matrix3D<float> im = m.inverse();
// cout << "im = " << endl << im << endl;
//
// cout << "m * im = " << endl << m * im << endl;
//
// Matrix3D<float> m1( 1 , 2 , 3 , 4 , 4 , 6 , 7 , 8 , 9 );
// cout << "m1 = " << endl << m1 << endl;
// Matrix3D<float> im1 = m1.inverse();
// cout << "im1 = " << endl << im1 << endl;
//
// Force<float> force;
// force.F = Vector3D<float>( 10.0 , -10.0 , 0.0 );
// force.Pt = Vector3D<float>( 0.5 , 0.5 , 0.0 );
// Torque<float> torque = force.computeTorque( Vector3D<float>( 0.0 , 0.0 , 0.0 ) );
//
// cout << "force : " << endl;
// cout << force << endl;
// cout << "force.computeTorque( Vector3D<float>( 0.0 , 0.0 , 0.0 ) ) = " << endl;
// cout << torque << endl;

// float m = 1500;
// Force<float> force;
// force.F = Vector3D<float>(981,0,0);
// force.Pt = Vector3D<float>(2.5,1.5,0);
// Vehicle2D<float> veh;
// veh.m = 1500;
// float a,b;
// a = 2.5;
// b = 0.8;
// float Ixx,Iyy,Izz;
// Ixx = m*a*a/12;
// Iyy = m*b*b/12;
// Izz = Ixx + Iyy;
// veh.I = Matrix3D<float>(Ixx,0,0,0,Iyy,0,0,0,Izz);
// veh.invI = veh.I.inverse();
// cout << endl << veh << endl;
// veh.addForce(force);
// float dt = 0.1;
// veh.update(dt);
// cout << endl << veh << endl;
// veh.update(dt);
// cout << endl << veh << endl;

// Vector3D<float> v4 = m * v3;
// cout << "v4 = " << v4 << endl;
// cout << "v4 = " << v4.squaredLength() << endl;

// float* f = new float[10];
// cout << "f["<< 0 << "] = " << f[0] << endl;
// int n = 0;
// f[++n] = 3.14;
// cout << "f[0] = " << f[0] << endl;
// cout << "f[1] = " << f[1] << endl;


Quaternion<float> q( cos(pi/4) , v1*sin(pi/4) );
cout << "q = " << q << endl;
Quaternion<float> q1 = q*q;
cout << "q*q = " << q*q << endl;
Quaternion<float> q2 = q*q1;
cout << "q*q*q = " << q*q*q << endl;
q2 = q2 * v2;
cout << "q1*q1*v2 = " << q2 << endl;
Quaternion<float> q3 = q.conjugate();
cout << "q3 = " << q3 << endl;
Quaternion<float> v = q.rotate(v1);
cout << "q.rotate(v1) = " << v << endl;
cout << "q.length() = " << q.length() << endl;
cout << "q.inverse() = " << q.inverse() << endl;
cout << "q*q.inverse() = " << q*q.inverse() << endl;
Matrix3D<float> m;
q.ToRotationMatrix(m);
cout << "m = " << endl << m << endl;
cout << "m.transpose() = " << endl << m.transpose() << endl;
cout << "m*m.transpose() = " << endl << m*m.transpose() << endl;


string s;
cin >> s;

return 0;
}

Merci à tous ceux qui pourront m'aider...
Messages postés
6535
Date d'inscription
lundi 16 décembre 2002
Statut
Modérateur
Dernière intervention
22 août 2010
8
C'est assez explicite: error: ISO C++ forbids declaration of `Vector3D' with no type
Vector3D operator*( const T a )const;

-> cette méthode retourne un Vector3D, ce qui est interdit (tu veux sans doute mettre Vector3D<T>)

_____________________________________
Un éditeur de ressources gratuit pour Windows
Messages postés
7
Date d'inscription
dimanche 2 février 2003
Statut
Membre
Dernière intervention
7 mai 2008

J'ai déjà essayé cette solution sans succès.
Il s'agit à mon avis d'un problème assez subtil.
La surchage des opérateurs ">>" et "<<" ne me posait aucun problème,
jusqu'à ce que je tente de modifier quelque chose dans le code.
As-tu essayé de le compiler chez toi?
Evidemment tu devrais te débarasser de certaines inclusions de fichiers
dans le main.
Tente une fois de compiler chez toi et dis-moi ce qu'il en est.
Moi j'ai utilisé Dev-cpp.
Messages postés
7
Date d'inscription
dimanche 2 février 2003
Statut
Membre
Dernière intervention
7 mai 2008

Pour les opérateurs ">>" et "<<",je viens de corriger le problème.
J'avais oublier de rajouter tous les using std::... après avoir supprimé
using namespace std.
Il n'empêche que le problème concernant la définition de Vector3D persiste:
j'ai tenté de réecrire le code sans templates(avec des floats à la
place de T,et j'ai toujours le même problème.Serait-ce un problème d'inclusion
de fichiers?
Messages postés
7
Date d'inscription
dimanche 2 février 2003
Statut
Membre
Dernière intervention
7 mai 2008

Ou alors,le type Vector3D<T> ne serait pas définit dans l'entête de Matrix3D.hpp,
d'où l'erreur à la compilation.
J'ai essayé de corriger le problème en définissant la surcharge de l'opérateur "*"
comme suit:

template<class T>

class Matrix3D
{
.
.
.
template<class U>
Vector3D operator*( const Vector3D& v )const;

};

Toujours sans succès.
Messages postés
6535
Date d'inscription
lundi 16 décembre 2002
Statut
Modérateur
Dernière intervention
22 août 2010
8
J'ai essayé de compiler et aucun problème.
J'ai mis ca dans mon main:

  Vector3D<float> v1(0,0,1);
  Matrix3D<float> im;

  cout << v1 << ", " << im << endl;

J'ai juste dû mettre des "return out" à la fin des méthodes operator<< (d'ailleurs, dans le << de Matrix3D, tu écris dans cout au lieu de out)

_____________________________________
Un éditeur de ressources gratuit pour Windows
Messages postés
7
Date d'inscription
dimanche 2 février 2003
Statut
Membre
Dernière intervention
7 mai 2008

Le monologue va finalement prendre fin.J'ai trouvé la solution du problème(je veux dire j'ai trouvé sur google. lol)
Il suffisait de virer l'inclusion du header "Vector3D.hpp" du header "Matrix3D.hpp" et d'ajouter avant la définition de la classe Matrix3D,la définition de la classe Vector 3D.

Ca donne donc:

Contenu du header Matrix3D.hpp:

//#include "Vector3D.hpp"

template<class T> class Vector3D;

template<class T>
class Matrix3D
{
public:
...
};

Et voilà,le tour est joué.
Messages postés
7
Date d'inscription
dimanche 2 février 2003
Statut
Membre
Dernière intervention
7 mai 2008

J'avais pas vu ton post.Tu as raison pour l'opérateur "<<" de Matrix3D,c'est "out <<" et non "cout<<" que je dois mettre.
Il semblerait que la solution de mon problème était de simplement mettre une définition de la classe Vector3D dans le header de Matrix3D sans inclure le fichier d'entête "Vector3D.hpp"...
L'erreur générée par le compilateur indique simplement que dans le header de Matrix3D,le type "Vector3D" est indéfini:il suffisait simplement de le définir avant de définir la classe Matrix3D...
J'avais essayé cette solution mais j'avais mis la définition suivante:
"template<class T> Vector3D" au lieu de la définition correcte,"template<class T> class Vector3D...