【问题标题】:Confusion between rvalue references and const lvalue references as parameter右值引用和作为参数的 const 左值引用之间的混淆
【发布时间】:2017-06-24 16:59:02
【问题描述】:

因此,复制构造函数的参数列表包含一个 const 左值引用,例如 const B& x。 但是,移动构造函数的参数列表包含一个右值引用,例如 B&& x

当我发现这一点时,我觉得很奇怪,所以我尝试定义一个以 const 左值引用作为参数的函数:

void calculator(const Intvec& veccor) 
{ 
cout << "in veccor" << veccor.m_size << "\n"; 
}

我已经知道 const 左值引用可以绑定到任何东西,所以结果是意料之中的。我尝试使用左值和右值调用该函数,正如预期的那样,一切正常:

calculator(Intvec(33)); //works
Intvec newvec(22);
calculator(newvec); //works

然后我尝试将calculator的参数列表更改为右值引用,正如预期的那样,调用它时只有右值起作用。

既然 const 左值引用可以同时接受左值和右值作为参数,为什么移动构造函数不只是使用 const 左值引用而不是右值引用呢? 为什么不总是使用 const 左值引用,就像在移动构造函数中发生的事情不同时那样?

【问题讨论】:

  • 因为它是const,所以在“窃取”它的内容之前,你必须把它扔掉(坏的)。此外,它(被移动的值)实际上可能已声明为const,从而导致您进入未定义的行为。

标签: c++


【解决方案1】:

如果移动构造函数接受 const 左值引用,则移动构造函数的此类声明将与复制构造函数没有区别。必须有一种方法来区分它们,并且已经指定了语言,以便移动构造函数将右值引用作为参数。

接受 const 左值引用的移动构造函数不允许修改从对象移动的对象,因此您无法执行在复制构造函数中无法执行的任何操作。事实上,这种移动构造函数在各方面都与复制构造函数相同。既然和拷贝构造函数完全一样,为什么还要称它为移动构造函数?


PS。你的实验揭示了一个有趣的事实:只要一个类有一个复制构造函数(并且移动构造函数没有被显式删除),它是否有一个移动构造函数并不影响该对象的使用方式。在任何适合移动的情况下,如果类没有移动构造函数,则可以使用副本代替。

【讨论】:

  • 实际上,准确地说,一个没有显式删除的移动构造函数的类,如果它有一个复制构造函数,它仍然被认为是可移动的。不可移动类是具有显式删除的移动构造函数的类,移动它是非法的,但复制它仍然是合法的。 Live
  • @PasserBy 好点。措辞现在应该更正确了。
猜你喜欢
  • 2020-08-24
  • 2017-03-26
  • 1970-01-01
  • 1970-01-01
  • 2021-11-30
  • 1970-01-01
  • 1970-01-01
  • 2014-09-09
  • 1970-01-01
相关资源
最近更新 更多