调用在复制参数值的函数中移动参数值的函数



我通过以下代码传递:

void enqueue(T&& value)
{
move_value_somewhere( T(std::move(value)));
}
void enqueue(const T& value)
{
enqueue(T(value));
}

复制输入参数的第二个函数调用移动输入参数的第一个函数。假设代码是正确的,如果从第二个函数调用值,T(std::move(value))怎么会不移动值而不是复制它,它可能来自T()但我不知道为什么。

enqueue(T(value));

首先创建传递值 (T(value)) 的临时副本。然后,您的移动构造函数enqeue移动该临时副本。因此,该代码类似于

T copy(value);
enqueue(std::move(copy));

void enqueue(const T& value)中,一个临时T是从value复制构造的。 然后将该临时传递给void enqueue(T&& value)

void enqueue(T&& value)中,另一个临时T是从value作为输入进行移动构造的(假设T有一个移动构造函数,否则它将被复制构造)。 然后将该临时传递给move_value_somewhere()。 该临时T实际上是不必要的,因为value已经是右值引用,因此可以直接将其移动到move_value_somewhere(),例如:

void enqueue(T&& value)
{
move_value_somewhere(std::move(value));
}

在复制构造函数中调用移动构造函数

实际上,事实并非如此,因为显示的代码根本不适用于构造函数,而仅适用于普通的非静态类方法。 那里有很大的不同。构造函数没有返回值,并且不能像此代码那样相互调用。 但它们可以相互委托,但只能从成员初始化列表中委派。 请参阅构造函数和成员初始值设定项列表。

enqueue()采用T&&,这仅将其限制为该类型,由于传递参数不会发生构造函数调用,因为它不是值类型。

但是,当您调用enqueue()时,您将创建一个临时T该将从您传入const T& value调用其复制构造函数。

随后,临时成为enqueue()的参数,进而创建另一个 prvalueT,这次使用您的(现在)lvalue 参数转换为T&&初始化,如果T确实有一个移动构造函数,它将调用它。

否则,如果T没有移动构造函数(也没有显式删除的构造函数),它将"回退"到调用复制构造函数(如果存在)。

由于您正在传递临时move_value_somewhere()因此它需要接受T&&const T&T- 根据规定类型T具有可行的构造函数来实现这一切。

最新更新