views:

38

answers:

2

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;
    }
+5  A: 

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.

Jerry Coffin
A: 

Is the Point class defined and compiled inside the same project as the main function? As templates are resolved at compile time, you cannot define a template in a second project, for example a static lib, and link against it. If you want it in a seperate project, you need to provide the full implementation inside the header and simply omit the template's source file. Upon including that header, when the file with your main function is compiled, the template will be compiled for its actual instantiations, in your case Point and Point.

Keep in mind this does required any linking in order to use the class, and a project consisting of template headers only would not produce a linkable lib anyway.

Mephane