具有不同数据类型的 C++ 中的二元运算符重载

Binary operator overloading in C++ with differing data types

我正在致力于用 C++ 实现 AVL 树。为了保持简洁(和练习),我试图重载树节点的比较运算符。

我希望树的 find 函数看起来像这样:

node* find(int key)
{
    node* currentNode = root;

    while (currentNode)
    {
        if (key < *currentNode)
        {
            currentNode = currentNode.getLeftChild();
        }
        else if (key > *currentNode)
        {
            currentNode = currentNode.getRightChild();
        }
        else
        {
            return currentNode;
        }
    }

    return nullptr;
}

在这种情况下,我可以重载运算符来比较 intnode,如下所示:

bool operator<(const int& lhs, const node& rhs)    // friend of node
{
    return lhs < rhs.key;
}

但这似乎只适用于 int < node 而不适用于 node < int。我需要为 node < int 定义一个单独的函数吗?

我还想将此函数模板化,以便我可以将任何东西(本身具有比较运算符)与 nodes:

进行比较
template<typename T> bool operator<(const T& lhs, const node& rhs)    // friend of node
{
    return lhs < rhs.key;
}

同样,这适用于 T < node 但不适用于 node < T。我是否需要为 node < T 定义一个函数以及上面的函数?

TL;DR

如果我将运算符重载为 bool operator<(const foo& lhs, const bar& rhs),我是否还需要定义 bool operator<(const bar& lhs, const foo& rhs) 以便操作数可以任意选择? template<typename T> bool operator<(const foo& lhs, const T& rhs)?

等模板函数也是如此吗?

抱歉,如果我在这里回答了我自己的问题,但我能找到的关于运算符重载的唯一资源仅显示了两个参数使用相同类型的示例。我只是想确定我做的是对的,希望这个 post 会在下次有人搜索这个问题时出现。

让我们看看您的功能和您使用的命名

bool operator<(const int& lhs, const node& rhs) 

因此 int 称为 lhsnode 称为 rhs。这些名称与类型所在的运算符的 side 匹配。 lhsleft hand side and rhsrhside。所以

bool operator<(const int& lhs, const node& rhs) 

只有当你有

时才会工作
int < node

如果你想拥有

node < int

那么你需要另一个函数,其中 nodelhsintrhs

bool operator<(const node& lhs, const int& rhs) 

现在您可以像这样制作模板

template<typename T> bool operator<(const T& lhs, const node& rhs)    // friend of node
{
    return lhs < rhs.key;
}

template<typename T> bool operator<(const node& lhs, const T& rhs)    // friend of node
{
    return lhs.key < rhs;
}

对于定义了 T < node::key 的所有类型,这将为您提供 operator <,其中 Tnode 出现在 [= 的任一 side 上30=].

它被认为是很好的做法。许多图书馆开发人员都以同样的方式做到了这一点。 boost 就是一个这样的例子,如果你分别定义这两个操作。

bool operator < (const foo& lhs, const bar& rhs);
bool operator < (const bar& lhs, const foo& rhs);

针对你的问题,如果你希望只有一个模板比较功能,你可以通过以下方式实现:

template<typename T>
bool less(const T& lhs, const T& rhs)
{
    return lhs < rhs;
}

class node
{
private:
    int nodeValue;

public:
    explicit node(int i):nodeValue(i){}

Below conversion function defined for comparison with int, same can be defined for char or a user defined data type

    operator int()const
    {
        return nodeValue;
    }
};

void test()
{
    node tmp(75);

    std::cout<<"less<int>(tmp, 10):"<<less<int>(tmp, 10)<<std::endl;
    std::cout<<"less<int>(10, tmp):"<<less<int>(10, tmp)<<std::endl;
}

在此基础上,您可以将此方法用于两种不同的用户定义日期类型,前提是它们具有定义为某些数据类型的转换函数,该数据类型定义了运算符 <