功能超载rvalue

Function overloading for rvalue

本文关键字:rvalue 超载 功能      更新时间:2023-10-16

我正在为二进制搜索树类实现 insert函数,有两个版本用于该函数,一个用lvalue项目称为lvalue项目(要插入到树上的项目)一个带有我使用std::move的rvalue。

第一个:

template <typename Comparable>
void BinarySearchTree<Comparable>::insert(const Comparable &x, BinaryNode* &t)
{
    if (t == nullptr)
        t = new BinaryNode(x, nullptr, nullptr);
    if (x < t->element)
        insert(x, t->left);
    if (x > t->element)
        insert(x, t->right);
}

第二个:

template <typename Comparable>
void BinarySearchTree<Comparable>::insert(Comparable &&x, BinaryNode* &t)
{
    if (t == nullptr)
        t = new BinaryNode(std::move(x), nullptr, nullptr);
    if (x < t->element)
        insert(x, t->left); // should this be insert(std::move(x), t->left)?
    if (x > t->element)
        insert(x, t->right); // also here?
}

第二个功能中insert的递归调用是否应使用xstd::move(x)

调用

我的猜测是它应该是 x,因为它已经是一个rvalue,并且不需要 move(),但是,指南实现我正在使用二手std::move()

首先,请考虑标准对那些可以移动的对象说的内容:

[...]将移动的对象放置在有效但未指定的状态中。

您不能期望它也适用于所有用户定义的类型,但这是一个常见的模式。
让我们假设Comparable是这种情况,并分析您的第二个功能:

template <typename Comparable>
void BinarySearchTree<Comparable>::insert(Comparable &&x, BinaryNode* &t)
{
    if (t == nullptr)
        t = new BinaryNode(std::move(x), nullptr, nullptr);
    if (x < t->element)
        insert(x, t->left); // should this be insert(std::move(x), t->left)?
    if (x > t->element)
        insert(x, t->right); // also here?
}

如果t等于nullptr,则在t中移动x
该操作之后,x在有效但未指定的状态中可能会发生。
这意味着x < t->element以及x > t->element具有不确定的行为。
换句话说,一旦将其移出后,您就不应使用对象。同样,您也不应移动两次相同的对象。

是否应使用X或STD :: Move(x)?

在第二个功能中插入的递归调用

您可以简单地将其重写:

template <typename Comparable>
void BinarySearchTree<Comparable>::insert(Comparable &&x, BinaryNode* &t)
{
    if (t == nullptr) {
        t = new BinaryNode(std::move(x), nullptr, nullptr);
    } else if (x < t->element) {
        insert(std::move(x), t->left);
    } else if (x > t->element) {
        insert(std::move(x), t->right);
    }
}

仅移动Comparable一次。