如何使用友元函数重载operator ==外部模板类?

时间:2015-10-24 02:14:08

标签: c++ templates overloading operator-keyword friend

我正在尝试编写一个重载 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

为什么呢?

4 个答案:

答案 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);
};

<强>参考
http://web.mst.edu/~nmjxv3/articles/templates.html

答案 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之前: - )