在复制参数值的函数中调用移动参数值的函数
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。
我通过了以下代码:
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。