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

Calling a function that moves the parameter value in a function that copies it

我通过了以下代码:

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));

enqueue() 采用 T&&,这只是将其限制为该类型,传递参数后不会发生构造函数调用,因为它不是 value-type.

然而,当您调用 enqueue() 时,您创建了一个临时 T,它将从您传递给它的 const T& value 调用它的 copy-constructor。

随后,临时变量成为 enqueue() 的参数,然后创建另一个纯右值 T,这次用你的(现在)左值参数初始化为 T&& , 如果 T 确实有移动构造函数,将调用它。

否则,如果 T 没有移动构造函数(也没有明确删除的构造函数),它将“fall-back”改为调用 copy-constructor(如果存在)。

由于您将临时传递给 move_value_somewhere(),因此需要接受 T&&const T&T - 前提是类型 T 有一个可行的构造函数使这一切成为可能。

void enqueue(const T& value) 中,T 来自 value 的临时 T 作为输入。然后将该临时传递给 void enqueue(T&& value).

void enqueue(T&& value)中,另一个临时T正在move-constructed从value作为输入(假设T有一个移动构造函数,否则它将是copy-constructed 代替)。然后将该临时文件传递给 move_value_somewhere()。那个临时的 T 实际上是不必要的,因为 value 已经是一个右值引用,所以它可以直接移动到 move_value_somewhere() ,例如:

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

The move constructor is called inside the copy constructor

实际上,它不是,因为显示的代码根本不是 构造函数,只是普通的 non-static class方法。那里有很大的不同。 构造函数 没有 return 值,并且不能像这段代码那样相互调用。但他们可以委托给对方,但只能从成员初始化列表中。参见 Constructors and member initializer lists