存在 std::move 时未使用移动语义

发布于 2024-12-17 05:39:34 字数 455 浏览 4 评论 0原文

具有以下内容:

#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() 被调用?

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

With the following:

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

Why is ifstream::operator=(const ifstream&) being called instead of ifstream::operator=(ifstream&&) even though std::move() is called?

Update: Generally speaking, is there a way to coerce a lvalue reference to a rvalue reference?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

忆悲凉 2024-12-24 05:39:34

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

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

为了确定起见,我在 ifstream::operator=(ifstream&&) 的实现中插入了一条 print 语句。当我执行你的程序时打印出:

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

What evidence do you have that ifstream::operator=(const ifstream&) is being called? Do you get a compile error that says you're calling this private or deleted member?

If your code is calling ifstream::operator=(const ifstream&), and if your implementation is claiming to be C++11, then this is a bug in either your C++ std::lib, or compiler. When I compile your code, ifstream::operator=(ifstream&&) gets called. And this is by design.

I stuck a print statement in my implementation of ifstream::operator=(ifstream&&) just to be sure. When I did your program prints out:

basic_ifstream<_CharT, _Traits>::operator=(basic_ifstream&& __rhs)
找回味觉 2024-12-24 05:39:34

标准

 27.9.1.8 Assign and swap [ifstream.assign]

       basic_ifstream& operator=(basic_ifstream&& rhs);

我假设您正在查看错误的代码(没有任何地方可以保证必须调用基类运算符 istream::operator=(istream&&) )?


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

是的,这就是 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;

函数做同样的事情,前提是 move 构造函数不抛出异常。

Standard

 27.9.1.8 Assign and swap [ifstream.assign]

       basic_ifstream& operator=(basic_ifstream&& rhs);

I assume you are looking at the wrong code (nowhere is it guaranteed that the base class operator istream::operator=(istream&&) must be called)?


Update: Generally speaking, is there a way to coerce a lvalue reference to a rvalue reference?

Yes, it is what std::move does:

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

There is also

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;

which does the same, provided that the moveconstructor is nothrow.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文