I'm trying to write a template class which overloads operator==. I know how to get it inside the class:
template <typename T>
class Point
{
private:
T x;
public:
Point(T X) : x(X) {}
bool operator== (Point &cP)
{
return (cP.x == x);
}
};
But now I want to achieve this outside the template class. I've read this post: error when trying to overload << operator and using friend function and add template declaration in my code:
template <typename> class Point;
template <typename T> bool operator== (Point<T>, Point<T>);
template <class T>
class Point
{
private:
T x;
public:
Point(T X) : x(X) {}
friend bool operator== (Point cP1, Point cP2);
};
template <class T>
bool operator== (Point<T> cP1, Point<T> cP2)
{
return (cP1.x == cP2.x)
}
However I still get a error: unresolved external symbol "bool __cdecl operator==(class Point<int>,class Point<int>)" (??8@YA_NV?$Point@H@@0@Z) referenced in function _main
And when I take away friend from :
friend bool operator== (Point cP1, Point cP2);
and want it to be member function, there would be a another error:
too many parameters for this function
why?
You have to put
friend
classes within each other, as well as in themselves. The Real one is named syntactically the same without replacing expressions. Sofriend bool operator==(P<T>,P<T>);
goes in both of the classes. So putfriend
before bool in the class T :-)This is a tricky issue: the friend declaration in the class will define a different friend function for each instantiation of your class. In other words,
Point<int>
andPoint<double>
will give rise to 2 different non-template friend functions. On the other hand, the outside function is a template function, not related to thefriend
inside the class. Solution: define the friend function inside the class. Due to friend name injection, it will be found successfully by ADL.@Kühl's answer is the most permissive approach to declare a templated friend function of a templated class. However, there is one unapparent side effect of this approach: All template instantiations of
Point
are friends with all template instantiations ofoperator==()
. An alternative is to make only the instantiation with the same type ofPoint
a friend. Which is done by adding a<T>
in the friend declaration ofoperator==()
.References
http://web.mst.edu/~nmjxv3/articles/templates.html
The declaration of the
operator==()
is a template. The declaration made afriend
is not a template but a non-template. To make the templateoperator==()
a friend you need to make the friend declaration a template, too: