问题
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?
回答1:
@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
回答2:
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>);
};
回答3:
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.
回答4:
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 :-)
来源:https://stackoverflow.com/questions/33313839/how-to-overload-operator-outside-template-class-using-friend-function