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?
@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 of operator==()
. An alternative is to make only the instantiation with the same type of Point
a friend. Which is done by adding a <T>
in the friend declaration of operator==()
.
template <typename T> class Point;
template <typename S>
bool operator== (Point<S>, Point<S>);
template <typename T>
class Point {
// ...
friend bool operator==<T> (Point, Point);
};
References
http://web.mst.edu/~nmjxv3/articles/templates.html
The declaration of the operator==()
is a template. The declaration made a friend
is not a template but a non-template. To make the template operator==()
a friend you need to make the friend declaration a template, too:
template <typename T> class Point;
template <typename S>
bool operator== (Point<S>, Point<S>);
template <typename T>
class Point {
// ...
template <typename S>
friend bool operator== (Point<S>, Point<S>);
};
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>
and Point<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 the friend
inside the class. Solution: define the friend function inside the class. Due to friend name injection, it will be found successfully by ADL.
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. So friend bool operator==(P<T>,P<T>);
goes in both of the classes. So put friend
before bool in the class T :-)