我正在尝试编写一个重载 operator == 的模板类。我知道如何在课堂上学习它:
template <typename T>
class Point
{
private:
T x;
public:
Point(T X) : x(X) {}
bool operator== (Point &cP)
{
return (cP.x == x);
}
};
但是现在我想在模板类之外实现这个目标。我看过这篇文章: @ViktorMaksimov并在我的代码中添加模板声明:
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 bool operator== (Point cP1, Point cP2);
并希望它成为成员函数,会出现另一个错误:
too many parameters for this function
为什么呢?
答案 0 :(得分:5)
@Kühl的回答是声明模板化类的模板化友元函数的最宽松方法。但是,此方法存在一个不明显的副作用:Point
的所有模板实例化都是operator==()
的所有模板实例化的朋友。另一种方法是仅使用相同类型的Point
朋友进行实例化。这是通过在<T>
的朋友声明中添加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);
};
答案 1 :(得分:3)
operator==()
的声明是一个模板。声明使friend
不是模板,而非模板。要使模板operator==()
成为朋友,您还需要将朋友声明设为模板:
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>);
};
答案 2 :(得分:0)
这是一个棘手的问题:班级中的朋友声明将为您的班级的每个实例化定义不同的朋友函数。换句话说,Point<int>
和Point<double>
将产生2个不同的非模板朋友函数。另一方面,外部函数是模板函数,与类中的friend
无关。解决方案:在类中定义友元函数。由于friend name injection, it will be found successfully by ADL。
答案 3 :(得分:-1)
您必须将friend
个类放在彼此之内,以及它们自身。在没有替换表达式的情况下,Real语法在语法上被命名为相同。所以friend bool operator==(P<T>,P<T>);
在两个类中都有。所以在课程T中将friend
放在bool之前: - )