我正在为一个二进制搜索树类实现一个insert函数,该函数有两个版本,一个是用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递归调用是用x还是std::move(x)调用?
我猜想它应该是x,因为它已经是一个rvalue,不需要move(),但是,我使用的指南实现使用的是std::move()
发布于 2016-12-17 23:13:44
首先,考虑一下标准对那些可以移动的对象说了什么:
..。移离对象应置于有效但未指定的状态。
您不能期望它也适用于所有用户定义的类型,但它是一个常见的模式。
让我们假设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。
https://stackoverflow.com/questions/41200827
复制相似问题