首页 文章

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

提问于
浏览
1

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

  • 0

    @Kühl 的答案是声明模板化类的模板化友元函数的最宽松方法 . 但是,此方法存在一个不明显的副作用: Point 的所有模板实例化都是 operator==() 的所有模板实例化的朋友 . 另一种方法是仅使用相同类型的 Point 朋友进行实例化 . 这是通过在 operator==() 的友元声明中添加 <T> 来完成的 .

    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

  • 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>);
    };
    
  • 5

    这是一个棘手的问题:类中的friend声明将定义您的类的 different friend函数 for each instantiation . 换句话说, Point<int>Point<double> 将产生2个不同的非模板友元函数 . 另一方面,外部函数是模板函数,与类中的 friend 无关 . 解决方案:在类中定义友元函数 . 由于friend name injection, it will be found successfully by ADL .

  • -1

    你必须将 friend 类放在彼此之内,以及它们自己 . 在没有替换表达式的情况下,Real语法在语法上被命名为相同 . 所以 friend bool operator==(P<T>,P<T>); 进入了这两个类 . 所以在课堂上把 friend 放在bool之前:-)

相关问题