Search code examples
c++templatesfriend

Friends, templates, overloading << linker errors


I had some good insight to an earlier post regarding this, but I have no idea what these compile errors mean that I could use some assistant on. Templates, friends, and overloading are all new, so 3 in 1 is giving me some problems...

1>main.obj : error LNK2019: unresolved external symbol "public: __thiscall Point<double>::Point<double>(double,double)" (??0?$Point@N@@QAE@NN@Z) referenced in function _main
1>main.obj : error LNK2019: unresolved external symbol "public: __thiscall Point<int>::Point<int>(int,int)" (??0?$Point@H@@QAE@HH@Z) referenced in function _main
1>C3_HW8.exe : fatal error LNK1120: 3 unresolved externals

Point.h

#ifndef POINT_H
#define POINT_H

#include <iostream>

template <class T>
class Point
{
public:
 Point();
 Point(T xCoordinate, T yCoordinate);
 template <class G>
 friend std::ostream &operator<<(std::ostream &out, const Point<G> &aPoint);

private:
 T xCoordinate;
 T yCoordinate;
};

#endif

Point.cpp

#include "Point.h"

template <class T>
Point<T>::Point() : xCoordinate(0), yCoordinate(0)
{}

template <class T>
Point<T>::Point(T xCoordinate, T yCoordinate) : xCoordinate(xCoordinate), yCoordinate(yCoordinate)
{}


template <class G>
std::ostream &operator<<(std::ostream &out, const Point<G> &aPoint)
{
 std::cout << "(" << aPoint.xCoordinate << ", " << aPoint.yCoordinate << ")";
 return out;
}

main.cpp

#include <iostream>
#include "Point.h"

int main()

    {
     Point<int> i(5, 4);
     Point<double> *j = new Point<double> (5.2, 3.3);
     std::cout << i << j;
    }

Solution

  • With most compilers, you need to put templates in headers, so they're visible to the compiler where they're used. If you really want to avoid that, you can use explicit instantiation of the template(s) over the necessary types, but putting them in a header is much more common.