c++ - 右值的函数重载

标签 c++ c++11 move-semantics overloading

我正在为一个二叉搜索树类实现一个 insert 函数,这个函数有两个版本,一个是用左值项(要插入到树中的项)调用的,另一个是一个在我使用 std::move 的地方有一个右值。

第一个:

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的递归调用应该用x调用还是用std::move(x)调用?

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

最佳答案

首先,考虑标准对那些可以 move 的对象的规定:

[...] moved-from objects shall be placed in a valid but unspecified state.

你不能期望它也适用于所有用户定义的类型,但它是一种常见模式。
我们假设 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 ,你动xt .
在该操作之后,可能会发生 x 处于有效但未指定的状态
这意味着 x < t->element以及x > t->element有未定义的行为。
换句话说,一旦您将对象移出,您就不应该再使用它。同样,您不应 move 同一对象两次。

Should the recursive call of insert in the second function be called with x or 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);
    }
}

move Comparable只有一次。

关于c++ - 右值的函数重载,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41200827/

相关文章:

c++ - 为什么 emplace_back 调用析构函数?

c++ - 返回一个右值——这段代码有什么问题?

c++ - 命名空间 std 中所有符号的列表

c++ - 条件 (SFINAE) 覆盖

c++ - 将 std::string 存储到 int[] 中用于 C++ 中的大整数

c++ - 通过自动解锁从类中返回锁定的资源

c++ - 我的标准偏差程序的输出问题

c++ - CGAL 错误 : Eigen3 is required -> Eigen seems to be okay though

c++ - Python 解析标准输入比 C++ 快得多

c++ - C++11 中返回 const 值类型对 move 语义的影响