我正在尝试编写一个重载 operator== 的模板类 . 我知道如何在课堂上学习它:
template <typename T>
class Point
{
private:
T x;
public:
Point(T X) : x(X) {}
bool operator== (Point &cP)
{
return (cP.x == x);
}
};
但是现在我想在模板类之外实现这个目标 . 我已经阅读了这篇文章:error when trying to overload << operator and using friend function并在我的代码中添加模板声明:
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)
}
但是我仍然收到错误: unresolved external symbol "bool __cdecl operator==(class Point<int>,class Point<int>)" (??8@YA_NV?$Point@H@@0@Z) referenced in function _main
当我带走 friend 时:
friend bool operator== (Point cP1, Point cP2);
并希望它成为成员函数,会有另一个错误:
too many parameters for this function
为什么?
4 回答
@Kühl 的答案是声明模板化类的模板化友元函数的最宽松方法 . 但是,此方法存在一个不明显的副作用:
Point
的所有模板实例化都是operator==()
的所有模板实例化的朋友 . 另一种方法是仅使用相同类型的Point
朋友进行实例化 . 这是通过在operator==()
的友元声明中添加<T>
来完成的 .References
http://web.mst.edu/~nmjxv3/articles/templates.html
operator==()
的声明是一个模板 . 声明使friend
不是模板而是非模板 . 要使模板operator==()
成为朋友,您还需要将朋友声明作为模板:这是一个棘手的问题:类中的friend声明将定义您的类的 different friend函数 for each instantiation . 换句话说,
Point<int>
和Point<double>
将产生2个不同的非模板友元函数 . 另一方面,外部函数是模板函数,与类中的friend
无关 . 解决方案:在类中定义友元函数 . 由于friend name injection, it will be found successfully by ADL .你必须将
friend
类放在彼此之内,以及它们自己 . 在没有替换表达式的情况下,Real语法在语法上被命名为相同 . 所以friend bool operator==(P<T>,P<T>);
进入了这两个类 . 所以在课堂上把friend
放在bool之前:-)