错误LNK2019:未解析的外部符号

时间:2015-04-17 11:51:21

标签: c++ templates visual-studio-2012 visual-c++

quaternion.h

 //****************************************************
    //* quaternion.h                                      *
    //*                                                  *
    //* Implementaion for a generalized quaternion class *   
    //*                                                  *
    //* Written 1.25.00 by Angela Bennett                *
    //****************************************************


    #ifndef _QUATERNION_H_
    #define _QUATERNION_H_

    //#include <iostream.h>
    #include <math.h>

    #ifdef SHOEMAKE
    #include "EulerAngles.h"
    #endif

    template<class _Tp> 
      class Quaternion
    {

     public:

      //Quaternion
      // -default constructor
      // -creates a new quaternion with all parts equal to zero
      Quaternion(void);

      //Quaternion
      // -constructor
      // -parametes : w, x, y, z elements of the quaternion
      // -creates a new quaternion based on the elements passed in
      Quaternion(_Tp wi, _Tp xi, _Tp yi, _Tp zi);

      //Quaternion
      // -constructor
      // -parameters : 4D vector
      // -creates a new quaternion based on the elements passed in
      Quaternion(_Tp v[4]);

      //Quaternion
      // -copy constructor
      // -parameters : const quaternion q
      // -creates a new quaternion based on the quaternion passed in
      Quaternion(const Quaternion<_Tp>& q); 

    #ifdef SHOEMAKE
      //Quaternion
      // -constructor
      // -parameters : yaw, pitch, and roll of an Euler angle
      // -creates a new quaternion based on the Euler elements passed in
      // -used with Shoemakes code
      Quaternion(_Tp e[3], int order);
    #endif  

      //~Quaternion
      // -default destructor
      ~Quaternion();

      //operator=
      // -parameters : q1- Quaternion object
      // -return values : Quaternion
      // -when called on quaternion q2 sets q2 to be an object of  q3 
     inline Quaternion<_Tp> operator = (const Quaternion<_Tp>& q);

      //operator+
      // -parameters : q1 - Quaternion object
      // -return value : Quaternion 
      // -when called on quaternion q2 adds q1 + q2 and returns the sum in a new quaternion
    inline  Quaternion<_Tp> operator + (const Quaternion<_Tp>& q);

      //operator-
      // -parameters : q1- Quaternion object
      // -return values : Quaternion 
      // -when called on q1 subtracts q1 - q2 and returns the difference as a new quaternion
    inline  Quaternion<_Tp> operator - (const Quaternion<_Tp>& q);

      //operator*
      // -parameters : q1 - Quaternion object
      // -return values : Quaternion 
      // -when called on a quaternion q2, multiplies q2 *q1  and returns the product in a new quaternion 
    inline  Quaternion<_Tp> operator * (const Quaternion<_Tp>& q);

      //operator/
      // -parameters : q1 and q2- Quaternion objects
      // -return values : Quaternion 
      // -divide q1 by q2 and returns the quotient as q1 
    inline  Quaternion<_Tp> operator / (Quaternion<_Tp>& q);

      //operator+=
      // -parameters : q1- Quaternion object
      // -return values : Quaternion 
      // -when called on quaternion q3 adds q1 and q3 and returns the sum as q3 
    inline  Quaternion<_Tp>& operator += (const Quaternion<_Tp>& q);

      //operator-=
      // -parameters : q1- Quaternion object
      // -return values : Quaternion 
      // -when called on quaternion q3, subtracts q1 from q3 and returns the difference as q3
    inline  Quaternion<_Tp>& operator -= (const Quaternion<_Tp>& q);

      //operator*=
      // -parameters : q1- Quaternion object
      // -return values : Quaternion 
      // -when called on quaternion q3, multiplies q3 by q1 and returns the product as q3
     inline Quaternion<_Tp>& operator *= (const Quaternion<_Tp>& q);

      //operator/=
      // -parameters : q1- Quaternion object
      // -return values : quaternion
      // -when called on quaternion q3, divides q3 by q1 and returns the quotient as q3
     inline Quaternion<_Tp>& operator /= (Quaternion<_Tp>& q);

      //operator<<
      // -parameters : ostream o, quaternion q
      // -return values :
      // -prints out a quaternion by it's components
     /* friend inline ostream& operator << (ostream& output, const Quaternion<_Tp>& q)
        {
          output << "[" << q.w << ", " << "(" << q.x << ", " << q.y << ", " << q.z << ")]";
          return output; 
        }
      */
      //operator!=
      // -parameters : q1 and q2- Quaternion objects
      // -return value : bool
      // -determines if q1 and q2 and equal
      bool operator != (const Quaternion<_Tp>& q);

      //operator==
      // -parameters : q1 and q2- Quaternion objects
      // -return value : bool
      // -determines if q1 and q2 and equal
      bool operator == (const Quaternion<_Tp>& q);  

      //other methods: norm, inverse, conjugate, toEuler

      //norm
      // -parameters : none
      // -return value : _Tp
      // -when called on a quaternion object q, returns the norm of q
      _Tp norm();

      //magnitude
      // -parameters : none
      // -return value : _Tp
      // -when called on a quaternion object q, returns the magnitude q
      _Tp magnitude();

      //scale
      // -parameters :  s- a value to scale q1 by
      // -return value: quaternion
      // -returns the original quaternion with each part, w,x,y,z, multiplied by some scalar s
    inline  Quaternion<_Tp> scale(_Tp s);

      //inverse
      // -parameters : none
      // -return value : quaternion
      // -when called on a quaternion object q, returns the inverse of q
     inline Quaternion<_Tp> inverse();

      //conjugate
      // -parameters : none
      // -return value : quaternion
      // -when called on a quaternion object q, returns the conjugate of q
     inline Quaternion<_Tp> conjugate();

      //UnitQuaternion
      // -parameters : none
      // -return value : quaternion
      // -when called on quaterion q, takes q and returns the unit quaternion of q
     inline Quaternion<_Tp> UnitQuaternion();

      // -parameters : 3D vector of type _Tp
      // -return value : void
      // -when given a  3D vector, v, rotates v by the quaternion
    inline  void QuatRotation(_Tp v[3]);

    #ifdef SHOEMAKE
      // -parameters : empty 3D vector, rotation order
      // -return : void
      // - converts this quaternion into Euler angles
      void toEuler(_Tp e[3], int order);
    #endifenter code here

     private:
      // [w, (x, y, z)]
      _Tp w, x, y, z;

    };

    #endif

quaternion.cpp

//****************************************************
//* quaternion.c++                                   *
//*                                                  *
//* Implementaion for a generalized quaternion class *   
//*                                                  *
//* Written 1.25.00 by Angela Bennett                *
//****************************************************


#include "quaternion.h"

//Quaternion
// -default constructor
// -creates a new quaternion with all parts equal to zero
template<class _Tp>
Quaternion<_Tp>::Quaternion(void)
{
  x = 0;
  y = 0;
  z = 0;
  w = 0;
}


//Quaternion
// -constructor
// -parametes : x, y, z, w elements of the quaternion
// -creates a new quaternion based on the elements passed in
template<class _Tp>
Quaternion<_Tp>::Quaternion(_Tp wi, _Tp xi, _Tp yi, _Tp zi)
{
  w = wi;
  x = xi;
  y = yi;
  z = zi;
}


//Quaternion
// -constructor
// -parameters : vector/array of four elements
// -creates a new quaternion based on the elements passed in
template<class _Tp>
Quaternion<_Tp>::Quaternion(_Tp v[4])
{
  w = v[0];
  x = v[1];
  y = v[2];
  z = v[3];
}


//Quaternion
// -copy constructor
// -parameters : const quaternion q
// -creates a new quaternion based on the quaternion passed in
template<class _Tp>
Quaternion<_Tp>::Quaternion(const Quaternion<_Tp>& q)
{
  w = q.w;
  x = q.x;
  y = q.y;
  z = q.z;
} 

#ifdef SHOEMAKE
//Quaternion
// -constructor
// -parameters : yaw, pitch, and roll of an Euler angle
// -creates a new quaternion based on the Euler elements passed in
// -used with Shoemakes code
template<class _Tp>
Quaternion<_Tp>::Quaternion(_Tp e[3], int order)
{
  EulerAngles ea;
  ea.x = e[0];
  ea.y = e[1];
  ea.z = e[2];
  ea.w = order;

  Quat q = Eul_ToQuat(ea);

  x = q.x;
  y = q.y; 
  z = q.z;
  w = q.w;
}
#endif

//~Quaternion
// -destructor
// -deleted dynamically allocated memory
template<class _Tp>
Quaternion<_Tp>::~Quaternion()
{
}


//operator=
// -parameters : q1 - Quaternion object
// -return value : Quaternion
// -when called on quaternion q2 sets q2 to be an object of  q3 
template<class _Tp>
Quaternion<_Tp> Quaternion<_Tp>::operator = (const Quaternion<_Tp>& q)
{
  w = q.w;
  x = q.x;
  y = q.y;
  z = q.z;

  return (*this);
}

//operator+
// -parameters : q1 - Quaternion object
// -return value : Quaternion 
// -when called on quaternion q2 adds q1 + q2 and returns the sum in a new quaternion
template<class _Tp>
Quaternion<_Tp> Quaternion<_Tp>::operator + (const Quaternion<_Tp>& q)
{
  return Quaternion(w+q.w, x+q.x, y+q.y, z+q.z);
}

//operator-
// -parameters : q1- Quaternion object
// -return values : Quaternion 
// -when called on q1 subtracts q1 - q2 and returns the difference as a new quaternion
template<class _Tp>
Quaternion<_Tp> Quaternion<_Tp>::operator - (const Quaternion<_Tp>& q)
{
  return Quaternion(w-q.w, x-q.x, y-q.y, z-q.z);
}


//operator*
// -parameters : q1 - Quaternion object
// -return values : Quaternion 
// -when called on a quaternion q2, multiplies q2 *q1  and returns the product in a new quaternion 
template<class _Tp>
Quaternion<_Tp> Quaternion<_Tp>::operator * (const Quaternion<_Tp>& q)
{
  return Quaternion(
   w*q.w - x*q.x - y*q.y - z*q.z, 
   w*q.x + x*q.w + y*q.z - z*q.y,                          
   w*q.y + y*q.w + z*q.x - x*q.z,
   w*q.z + z*q.w + x*q.y - y*q.x);
}

//operator/
// -parameters : q1 and q2- Quaternion objects
// -return values : Quaternion 
// -divide q1 by q2 and returns the quotient q1
template<class _Tp> 
Quaternion<_Tp> Quaternion<_Tp>::operator / (Quaternion<_Tp>& q)
{
  return ((*this) * (q.inverse()));
}


//operator+=
// -parameters : q1- Quaternion object
// -return values : Quaternion 
// -when called on quaternion q3, adds q1 and q3 and returns the sum as q3
template<class _Tp>
Quaternion<_Tp>& Quaternion<_Tp>::operator += (const Quaternion<_Tp>& q)
{
  w += q.w;
  x += q.x;
  y += q.y;
  z += q.z;

  return (*this);
}


//operator-=
// -parameters : q1- Quaternion object
// -return values : Quaternion 
// -when called on quaternion q3, subtracts q1 from q3 and returns the difference as q3
template<class _Tp>
Quaternion<_Tp>& Quaternion<_Tp>::operator -= (const Quaternion<_Tp>& q)
{
  w -= q.w;
  x -= q.x;
  y -= q.y;
  z -= q.z;

  return (*this);
}


//operator*=
// -parameters : q1- Quaternion object
// -return values : Quaternion 
// -when called on quaternion q3, multiplies q3 by q1 and returns the product as q3
template<class _Tp> 
Quaternion<_Tp>& Quaternion<_Tp>::operator *= (const Quaternion<_Tp>& q)
{
   _Tp w_val = w*q.w - x*q.x - y*q.y - z*q.z;
   _Tp x_val = w*q.x + x*q.w + y*q.z - z*q.y; 
   _Tp y_val = w*q.y + y*q.w + z*q.x - x*q.z;
   _Tp z_val = w*q.z + z*q.w + x*q.y - y*q.x; 

   w = w_val;
   x = x_val;
   y = y_val;
   z = z_val;

   return (*this);
}


//operator/=
// -parameters : q1- Quaternion object
// -return values : quaternion
// -when called on quaternion q3, divides q3 by q1 and returns the quotient as q3
template<class _Tp> 
Quaternion<_Tp>& Quaternion<_Tp>::operator /= (Quaternion<_Tp>& q)
{
  (*this) = (*this)*q.inverse();
  return (*this);
}


//operator!=
// -parameters : q1 and q2- Quaternion objects
// -return value : bool
// -determines if q1 and q2 are not equal
template<class _Tp>
bool Quaternion<_Tp>::operator != (const Quaternion<_Tp>& q)
{
  return (w!=q.w || x!=q.x || y!=q.y || z!=q.z) ? true : false;
}

//operator==
// -parameters : q1 and q2- Quaternion objects
// -return value : bool
// -determines if q1 and q2 are equal
template<class _Tp>
bool Quaternion<_Tp>::operator == (const Quaternion<_Tp>& q)
{
  return (w==q.w && x==q.x && y==q.y && z==q.z) ? true : false;
}  

//norm
// -parameters : none
// -return value : _Tp
// -when called on a quaternion object q, returns the norm of q
template<class _Tp>
_Tp Quaternion<_Tp>::norm()
{
  return (w*w + x*x + y*y + z*z);  
}

//magnitude
// -parameters : none
// -return value : _Tp
// -when called on a quaternion object q, returns the magnitude q
template<class _Tp>
_Tp Quaternion<_Tp>::magnitude()
{
  return sqrt(norm());
}

//scale
// -parameters :  s- a value to scale q1 by
// -return value: quaternion
// -returns the original quaternion with each part, w,x,y,z, multiplied by some scalar s
template<class _Tp>
Quaternion<_Tp> Quaternion<_Tp>::scale(_Tp  s)
{
   return Quaternion(w*s, x*s, y*s, z*s);
}

// -parameters : none
// -return value : quaternion
// -when called on a quaternion object q, returns the inverse of q
template<class _Tp>
Quaternion<_Tp> Quaternion<_Tp>::inverse()
{
  return conjugate().scale(1/norm());
}

//conjugate
// -parameters : none
// -return value : quaternion
// -when called on a quaternion object q, returns the conjugate of q
template<class _Tp>
Quaternion<_Tp> Quaternion<_Tp>::conjugate()
{
  return Quaternion(w, -x, -y, -z);
}

//UnitQuaternion
// -parameters : none
// -return value : quaternion
// -when called on quaterion q, takes q and returns the unit quaternion of q
template<class _Tp>
Quaternion<_Tp> Quaternion<_Tp>::UnitQuaternion()
{
  return (*this).scale(1/(*this).magnitude());
}

// -parameters : vector of type _Tp
// -return value : void
// -when given a 3D vector, v, rotates v by this quaternion
template<class _Tp>
void Quaternion<_Tp>::QuatRotation(_Tp v[3])
{
  Quaternion <_Tp> qv(0, v[0], v[1], v[2]);
  Quaternion <_Tp> qm = (*this) * qv * (*this).inverse();

  v[0] = qm.x;
  v[1] = qm.y;
  v[2] = qm.z;  
}

#ifdef SHOEMAKE
// -parameters : integer order- which will specify the order of the rotation, q- quaternion
// -return value : Euler angle
// -
template<class _Tp>
void Quaternion<_Tp>::toEuler(_Tp e[3], int order)
{
  Quat q;

  q.w = 0;
  q.x = e[0];
  q.y = e[1];
  q.z = e[2];

  EulerAngles ea = Eul_FromQuat(q, order);

  w = ea.w;
  x = ea.x;
  y = ea.y;
  z = ea.z;
}
#endif 

Main.cpp

// Quaternion test class

#include "quaternion.h"

int main(int argc, char **argv)
{
  cout << "Quaternion class test" << endl;

  cout << "Constructors:" << endl;
  float vect[4] = { 5, 6, 7, 8 };
  float v[3]= { 1.1, 2.34, 7.65 };
  Quaternion <float> q1;
  Quaternion <float> q2(1.0f, 2.0f, 3.0f, 4.0f);
  Quaternion <float> q3(q2);
  Quaternion <float> q4(vect);
  Quaternion <float> q7(3.0f, 1.0f, -2.0f, 1.0f);
  Quaternion <float> q8(2.0f, -1.0f, 2.0f, 3.0f);
  Quaternion <float> q9(3.0f, 1.0f, -2.0f, 1.0f);
  Quaternion <float> q16(0.0f, 1.1f, 2.34f, 7.65f);

  cout << "q1=" << q1 << endl;
  cout << "q2=" << q2 << endl;
  cout << "q3=" << q3 << endl;
  cout << "q4=" << q4 << endl;

  cout << "Operators:" << endl;
  cout << "Operator =" << endl;
  Quaternion <float> q5 = q2;
  cout << "q5 = " << q5 << endl;
  cout << "Operator +" << endl;
  Quaternion <float> q6 =  q5 + q4;
  cout << "q5 + q4 = " << q6 << endl;  //should equal (6,8,10,12)
  cout << "Operator -" << endl;
  q6 = q5 - q4;
  cout << "q5 - q4 = " << q6 << endl;  //should equal (-4,-4,-4,-4)
  cout << "Operator *" << endl;
  q6 = q7 * q8;
  cout << "q7  * q8 = " << q6 << endl; //should equal (8,-9,-2,11) 
  cout << "Operator /" << endl;
  q6 = q8.inverse();
  cout << "q7/(q8.inverse) = " << q7/q6 << endl;//should equal [8, (-9, -2, 11)]
  cout << "Operator += " << endl;
  q4 += q5;
  cout << "q4 += q5 is " << q4 << endl;//should equal [6, (8, 10, 12)]
  cout << "Operator -= " << endl;
  q5 -= q5;
  cout << "q5 -= q5 is " << q5 << endl;//should equal [0, (0, 0, 0)]
  cout << "Operator *= " << endl;
  q7 *= q8;
  cout << "q7 *= q8 is " << q7 << endl;//should equal [8, (-9, -2, 11)]
  cout << "Operator /= " << endl;
  q7= q9;
  q6 = q8.inverse();
  q7/=q6;
  cout << "q7 /= q8.inverse() is " << q7 << endl;//should equal [8, (-9, -2, 11)]
  cout << "Operator != " << endl;
  if (q2 != q2)
    cout << "doesn't work:(" << endl;
  else
    cout << "works!" << endl;
  cout << "Operator == " << endl;
  if (q2 == q2)
    cout << "works!" << endl;
  else
    cout << "doesn't work:(" << endl;
  cout << "Norm of q2 = " << q2.norm() << endl; //30
  cout << "Magnitude of q2 = " << q2.magnitude() << endl; //5.4772255....
  q6 = q2.scale(2);
  cout << "Scale of q2 by 2 = " << q6 << endl;//should equal [2, (4, 6, 8)]
  cout << "Inverse of q8 = " << q8.inverse() << endl;//should equal [0.111..., (0.0555..., -0.111..., -0.1666...)]
  cout << "Conjugate of q8 = " << q8.conjugate() <<endl;  //should equal (2,1,-2,-3)
  cout << "Unit Quaternion of q8 is " << q8.UnitQuaternion() << endl;
  //QuatRot 
  q8.QuatRotation(v);
  cout << "Rotate q8 by 1.1, 2.34, 7.65 = " << v[0] << ", " << v[1] << ", " << v[2] << endl;
   //should get the same answer as QuatRot(v, q8) ignoring the w factor
  q2=q8*q16;
  q3=q2*(q8.inverse());
  cout << q3 << endl;

#ifdef SHOEMAKE
  float v1[3] = { 2.3f, 3.2f, 4.3f };
  cout << "\nEuler -> Quaternion convertion test:" << endl;
  cout << " -in vector: (" << v1[0] << ", " << v1[1] << ", " << v1[2] << ")" << endl;
  Quaternion <float> q10(v1, EulOrdZYXs);
  cout << " -out quaternion: " << q10 << endl;
  cout << "Quaternion -> Euler convertion test:" << endl;
  cout << " -in quaternion: " << q10 << endl;
  q10.toEuler(v1, EulOrdZYXs);
  cout << " -out vector: (" << v1[0] << ", " << v1[1] << ", " << v1[2] << ")" << endl;
#endif

  return 1;
}

我在Visual Studio 2012中创建了基于Quaternion的示例项目。我从http://www.ncsa.illinois.edu/People/kindr/emtc/quaternions/获得了此代码示例,但在编译时它会抛出以下错误:

Error   24  error LNK2019: unresolved external symbol "public: void __thiscall Quaternion<float>::QuatRotation(float * const)" (?QuatRotation@?$Quaternion@M@@QAEXQAM@Z) referenced in function _main   c:\Users\BHC0006\documents\visual studio 2012\Projects\sampleQuad\sampleQuad\test.obj   sampleQuad
Error   18  error LNK2019: unresolved external symbol "public: float __thiscall Quaternion<float>::norm(void)" (?norm@?$Quaternion@M@@QAEMXZ) referenced in function _main  c:\Users\BHC0006\documents\visual studio 2012\Projects\sampleQuad\sampleQuad\test.obj   sampleQuad
Error   19  error LNK2019: unresolved external symbol "public: float __thiscall Quaternion<float>::magnitude(void)" (?magnitude@?$Quaternion@M@@QAEMXZ) referenced in function _main    c:\Users\BHC0006\documents\visual studio 2012\Projects\sampleQuad\sampleQuad\test.obj   sampleQuad
Error   23  error LNK2019: unresolved external symbol "public: class Quaternion<float> __thiscall Quaternion<float>::UnitQuaternion(void)" (?UnitQuaternion@?$Quaternion@M@@QAE?AV1@XZ) referenced in function _main    c:\Users\BHC0006\documents\visual studio 2012\Projects\sampleQuad\sampleQuad\test.obj   sampleQuad
Error   20  error LNK2019: unresolved external symbol "public: class Quaternion<float> __thiscall Quaternion<float>::scale(float)" (?scale@?$Quaternion@M@@QAE?AV1@M@Z) referenced in function _main    c:\Users\BHC0006\documents\visual studio 2012\Projects\sampleQuad\sampleQuad\test.obj   sampleQuad
Error   7   error LNK2019: unresolved external symbol "public: class Quaternion<float> __thiscall Quaternion<float>::operator=(class Quaternion<float> const &)" (??4?$Quaternion@M@@QAE?AV0@ABV0@@Z) referenced in function _main  c:\Users\BHC0006\documents\visual studio 2012\Projects\sampleQuad\sampleQuad\test.obj   sampleQuad
Error   8   error LNK2019: unresolved external symbol "public: class Quaternion<float> __thiscall Quaternion<float>::operator+(class Quaternion<float> const &)" (??H?$Quaternion@M@@QAE?AV0@ABV0@@Z) referenced in function _main  c:\Users\BHC0006\documents\visual studio 2012\Projects\sampleQuad\sampleQuad\test.obj   sampleQuad
Error   11  error LNK2019: unresolved external symbol "public: class Quaternion<float> __thiscall Quaternion<float>::operator/(class Quaternion<float> &)" (??K?$Quaternion@M@@QAE?AV0@AAV0@@Z) referenced in function _main    c:\Users\BHC0006\documents\visual studio 2012\Projects\sampleQuad\sampleQuad\test.obj   sampleQuad
Error   10  error LNK2019: unresolved external symbol "public: class Quaternion<float> __thiscall Quaternion<float>::operator*(class Quaternion<float> const &)" (??D?$Quaternion@M@@QAE?AV0@ABV0@@Z) referenced in function _main  c:\Users\BHC0006\documents\visual studio 2012\Projects\sampleQuad\sampleQuad\test.obj   sampleQuad
Error   9   error LNK2019: unresolved external symbol "public: class Quaternion<float> __thiscall Quaternion<float>::operator-(class Quaternion<float> const &)" (??G?$Quaternion@M@@QAE?AV0@ABV0@@Z) referenced in function _main  c:\Users\BHC0006\documents\visual studio 2012\Projects\sampleQuad\sampleQuad\test.obj   sampleQuad
Error   21  error LNK2019: unresolved external symbol "public: class Quaternion<float> __thiscall Quaternion<float>::inverse(void)" (?inverse@?$Quaternion@M@@QAE?AV1@XZ) referenced in function _main  c:\Users\BHC0006\documents\visual studio 2012\Projects\sampleQuad\sampleQuad\test.obj   sampleQuad
Error   22  error LNK2019: unresolved external symbol "public: class Quaternion<float> __thiscall Quaternion<float>::conjugate(void)" (?conjugate@?$Quaternion@M@@QAE?AV1@XZ) referenced in function _main  c:\Users\BHC0006\documents\visual studio 2012\Projects\sampleQuad\sampleQuad\test.obj   sampleQuad
Error   12  error LNK2019: unresolved external symbol "public: class Quaternion<float> & __thiscall Quaternion<float>::operator+=(class Quaternion<float> const &)" (??Y?$Quaternion@M@@QAEAAV0@ABV0@@Z) referenced in function _main   c:\Users\BHC0006\documents\visual studio 2012\Projects\sampleQuad\sampleQuad\test.obj   sampleQuad
Error   15  error LNK2019: unresolved external symbol "public: class Quaternion<float> & __thiscall Quaternion<float>::operator/=(class Quaternion<float> &)" (??_0?$Quaternion@M@@QAEAAV0@AAV0@@Z) referenced in function _main    c:\Users\BHC0006\documents\visual studio 2012\Projects\sampleQuad\sampleQuad\test.obj   sampleQuad
Error   14  error LNK2019: unresolved external symbol "public: class Quaternion<float> & __thiscall Quaternion<float>::operator*=(class Quaternion<float> const &)" (??X?$Quaternion@M@@QAEAAV0@ABV0@@Z) referenced in function _main   c:\Users\BHC0006\documents\visual studio 2012\Projects\sampleQuad\sampleQuad\test.obj   sampleQuad
Error   13  error LNK2019: unresolved external symbol "public: class Quaternion<float> & __thiscall Quaternion<float>::operator-=(class Quaternion<float> const &)" (??Z?$Quaternion@M@@QAEAAV0@ABV0@@Z) referenced in function _main   c:\Users\BHC0006\documents\visual studio 2012\Projects\sampleQuad\sampleQuad\test.obj   sampleQuad
Error   17  error LNK2019: unresolved external symbol "public: bool __thiscall Quaternion<float>::operator==(class Quaternion<float> const &)" (??8?$Quaternion@M@@QAE_NABV0@@Z) referenced in function _main   c:\Users\BHC0006\documents\visual studio 2012\Projects\sampleQuad\sampleQuad\test.obj   sampleQuad
Error   16  error LNK2019: unresolved external symbol "public: bool __thiscall Quaternion<float>::operator!=(class Quaternion<float> const &)" (??9?$Quaternion@M@@QAE_NABV0@@Z) referenced in function _main   c:\Users\BHC0006\documents\visual studio 2012\Projects\sampleQuad\sampleQuad\test.obj   sampleQuad
Error   2   error LNK2019: unresolved external symbol "public: __thiscall Quaternion<float>::Quaternion<float>(void)" (??0?$Quaternion@M@@QAE@XZ) referenced in function _main  c:\Users\BHC0006\documents\visual studio 2012\Projects\sampleQuad\sampleQuad\test.obj   sampleQuad
Error   3   error LNK2019: unresolved external symbol "public: __thiscall Quaternion<float>::Quaternion<float>(float,float,float,float)" (??0?$Quaternion@M@@QAE@MMMM@Z) referenced in function _main   c:\Users\BHC0006\documents\visual studio 2012\Projects\sampleQuad\sampleQuad\test.obj   sampleQuad
Error   4   error LNK2019: unresolved external symbol "public: __thiscall Quaternion<float>::Quaternion<float>(float * const)" (??0?$Quaternion@M@@QAE@QAM@Z) referenced in function _main  c:\Users\BHC0006\documents\visual studio 2012\Projects\sampleQuad\sampleQuad\test.obj   sampleQuad
Error   5   error LNK2019: unresolved external symbol "public: __thiscall Quaternion<float>::Quaternion<float>(class Quaternion<float> const &)" (??0?$Quaternion@M@@QAE@ABV0@@Z) referenced in function _main  c:\Users\BHC0006\documents\visual studio 2012\Projects\sampleQuad\sampleQuad\test.obj   sampleQuad
Error   6   error LNK2019: unresolved external symbol "public: __thiscall Quaternion<float>::~Quaternion<float>(void)" (??1?$Quaternion@M@@QAE@XZ) referenced in function _main c:\Users\BHC0006\documents\visual studio 2012\Projects\sampleQuad\sampleQuad\test.obj   sampleQuad
Error   25  error LNK1120: 23 unresolved externals  c:\users\bhc0006\documents\visual studio 2012\Projects\sampleQuad\Debug\sampleQuad.exe  sampleQuad
  1. 为什么会出现这种错误?

  2. 如何纠正此错误?

  3. 使用C ++计算四元数轮换的任何其他解决方案?

1 个答案:

答案 0 :(得分:0)

这些错误是源文件(.cpp)中模板定义的结果。在编译Main.cpp时尝试实例化模板时,编译器没有完整的类型信息,因为完整类型信息包含在单独的编译单元(Quaternion.cpp文件)中。因此,当链接器试图在Main.cpp中找到与相关模板实例化相对应的符号时,它就不能。您可以使用以下方法之一解决此问题:

  • 将模板定义移动到四元数头文件中,以便在编译Main.cpp
  • 时知道
  • 明确地实例化模板,例如template class Quaternion<float>;

在此处查看更多内容:Storing C++ template function definitions in a .CPP file