我试图更好地理解 C++ 中的值类别,但我遇到了一些让我有点困惑的代码。
我查看了一些问题,例如通过值或右值引用接受仅移动参数或如何通过值传递仅移动类型(例如std::unique_ptr)?,但我没有找到任何问题注释解释了幕后发生的情况,或者为什么可以按值传递仅移动类型的右值作为参数。就拿下面的例子来说吧:
class Foo
{
Foo(std::thread t) : mT(std::move(t))
private:
std::thread mT;
};
int main()
{
std::thread t;
Foo f(t); // doesn't compile as std::thread is not copyable
Foo f{std::thread()}; // compiles just fine using an rvalue
}
调用
Foo f(t);
会调用 std::thread
不存在的复制构造函数。然而,当用右值 Foo
构造一个 std::thread()
对象时,会发生什么情况而不发生同样的情况呢?为什么rvalue
没有被复制?
为什么右值没有被复制?
表达式
std::thread()
是参数t
的初始化。这和为什么你写了std::thread t;
却没有副本是一样的。
在
Foo::Foo
的实现中,对象t
被传递给std::move
,后者将其转换为右值引用,以便它与std::thread::thread(std::thread&&)
匹配,即线程的移动构造函数。