【问题标题】:how to overload operator == outside template class using friend function?如何使用友元函数在模板类之外重载运算符 ==?
【发布时间】:2016-01-23 16:03:07
【问题描述】:

我正在尝试编写一个重载 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&lt;int&gt;,class Point&lt;int&gt;)" (??8@YA_NV?$Point@H@@0@Z) referenced in function _main

当我带走 朋友 时:

friend bool operator== (Point cP1, Point cP2);

并希望它成为成员函数,会有另一个错误:

too many parameters for this function

为什么?

【问题讨论】:

  • 或者在静态函数中做==的工作,在类定义中内联实现友元操作符,调用静态函数,后面可以实现。

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


【解决方案1】:

@Kühl 的回答是声明模板类的模板友元函数的最宽松方法。但是,这种方法有一个不明显的副作用:Point 的所有模板实例化都是 operator==() 的所有模板实例化的朋友。另一种方法是仅将具有相同类型的Point 实例化为朋友。这是通过在operator==() 的朋友声明中添加&lt;T&gt; 来完成的。

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

【讨论】:

  • 为什么要在 operator== 之后添加 ?初始化模板函数不需要而是模板类。
  • 我知道...专业化
【解决方案2】:

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

【讨论】:

  • 使用模板operator==而不是非模板朋友有优势吗?如果我们想比较不同类型的点,这当然是有道理的,template&lt;typename S1, typename S2&gt; friend bool operator==(Point&lt;S1&gt;, Point&lt;S2&gt;);
  • @vsoftco:在这种特殊情况下,我没有看到优势。如果被友好的函数恰好被命名,它允许显式指定模板参数(对于运算符,可以在使用函数调用表示法时指定模板参数)。
  • 谢谢!现在我知道声明operator==() 和声明friend 是不一样的。
【解决方案3】:

这是一个棘手的问题:类中的友元声明将为类的每个实例化定义一个不同的友元函数。换句话说,Point&lt;int&gt;Point&lt;double&gt; 将产生 2 个不同的非模板友元函数。另一方面,外部函数是模板函数,与类内部的friend 无关。解决方法:在类内部定义友元函数。由于friend name injection, it will be found successfully by ADL.

【讨论】:

    【解决方案4】:

    您必须将friend 类放在彼此之间,以及它们本身。 Real 的名称在语法上相同,无需替换表达式。所以friend bool operator==(P&lt;T&gt;,P&lt;T&gt;); 参加了这两个课程。所以把friend放在T类的bool之前:-)

    【讨论】:

    • 如果operator== 进入两个类,我认为调用它不影响。
    • 如果您阅读 Bjarne 的 C++ 语言,它指出一个应该属于它所在的类,另一个应该完全相同。他们都应该是朋友,
    猜你喜欢
    • 2011-05-08
    • 1970-01-01
    • 2021-05-18
    • 2011-06-07
    • 2010-11-20
    • 2011-04-28
    相关资源
    最近更新 更多