-3

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;
}

I have created Quaternion-based sample project in Visual Studio 2012. I got this code sample from http://www.ncsa.illinois.edu/People/kindr/emtc/quaternions/, but in compile time it throws following errors:

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. Why I getting this kind of error?

  2. How do I rectify this error?

  3. Any other solution for calculation Quaternion rotation using C++?

SomeWittyUsername
  • 18,025
  • 3
  • 42
  • 85
kirubha
  • 13
  • 5
  • 1
    can you really make a minimum example? Like, throw out everything from your source code and post what is necessary to get the error? – Marcus Müller Apr 17 '15 at 11:55
  • possible duplicate of [What is an undefined reference/unresolved external symbol error and how do I fix it?](http://stackoverflow.com/questions/12573816/what-is-an-undefined-reference-unresolved-external-symbol-error-and-how-do-i-fix) – Peter O. Apr 21 '15 at 14:51

1 Answers1

0

These errors are the result of your template definitions inside source file (.cpp). The compiler doesn't have the full type information when trying to instantiate template while compiling Main.cpp because the full type information is contained in a separate compilation unit (the Quaternion.cpp file). Therefore, when the linker tries to find the symbols corresponding to the relevant template instantiation in Main.cpp, it can't. You can resolve this problem in one of these methods:

  • Move the template definition into the quaternion header file, so it will be known when compiling Main.cpp
  • Explicitly instantiate template, e.g.template class Quaternion<float>;

See more here: Storing C++ template function definitions in a .CPP file

Community
  • 1
  • 1
SomeWittyUsername
  • 18,025
  • 3
  • 42
  • 85