【问题标题】:move semantics unused in presence of std::move存在 std::move 时未使用的移动语义
【发布时间】:2012-01-02 20:34:08
【问题描述】:

以下内容:

#include <iostream>
#include <fstream>
using namespace std;
int main() {
    ifstream f;
    ifstream g;
    f = std::move(g);
}

为什么ifstream::operator=(const ifstream&)被调用而不是ifstream::operator=(ifstream&&)即使std::move()被调用?

更新:一般来说,有没有办法将左值引用强制为右值引用?

【问题讨论】:

  • istream::operator=(istream&amp;&amp;) 存在吗?
  • @iammilind 见sehe的回答。
  • @iammilind:是的,但它受到保护(参见第 27.7.2.1.2 节类 basic_istream 分配和交换)

标签: c++ c++11 rvalue-reference noncopyable


【解决方案1】:

你有什么证据表明ifstream::operator=(const ifstream&amp;) 正在被呼叫?您是否收到编译错误,说明您正在调用此私有或已删除成员?

如果您的代码调用 ifstream::operator=(const ifstream&amp;),并且如果您的实现声称是 C++11,那么这是您的 C++ std::lib 或编译器中的错误。当我编译你的代码时,ifstream::operator=(ifstream&amp;&amp;) 被调用。这是设计使然。

为了确定,我在ifstream::operator=(ifstream&amp;&amp;) 的实现中添加了一条打印语句。当我打印出你的程序时:

basic_ifstream<_CharT, _Traits>::operator=(basic_ifstream&& __rhs)

【讨论】:

  • 看起来这个相当烦人的 bug 在 gcc 中已经存在了一段时间。是时候打开错误报告了。
  • 另外,你用的是哪个编译器?
  • 抱歉,这不是 gcc 错误,而是 libstdc++ 错误,因为 basic_ifstream&lt;_CharT, _Traits&gt;::operator=(basic_ifstream&amp;&amp; __rhs) 甚至没有定义。
【解决方案2】:

标准

 27.9.1.8 Assign and swap [ifstream.assign]

       basic_ifstream& operator=(basic_ifstream&& rhs);

我假设您正在查看错误的代码(无法保证基类运算符istream::operator=(istream&amp;&amp;) 必须被调用)?


更新:一般来说,有没有办法将左值引用强制为右值引用?

是的,std::move 就是这样做的:

template <class T> typename remove_reference<T>::type&& move(T&& t) noexcept;

还有

template <class T> typename conditional<
  !is_nothrow_move_constructible<T>::value && is_copy_constructible<T>::value,
  const T&, T&&>::type move_if_noexcept(T& x) noexcept;

只要 moveconstructor 是 nothrow,它的作用也是一样的。

【讨论】:

  • 我忘了是基类还是派生类有MoveAssignable。已编辑的问题。
猜你喜欢
  • 2011-07-28
  • 2011-07-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-09-29
  • 1970-01-01
  • 1970-01-01
  • 2018-05-09
相关资源
最近更新 更多