【问题标题】:Why doesnt istream support rvalue extraction为什么 istream 不支持右值提取
【发布时间】:2018-11-03 01:08:12
【问题描述】:

我有一个围绕std::string 提供格式的类:

struct Wrap {
  std::string& s; // need const ref for output, non const for input 
  friend std::ostream& operator<< (std::ostream& os, const Wrap& w) {
    os << "[" << w.s << "]";
    return os;
  }
  friend std::istream& operator>> (std::istream& is, Wrap&& w) {
    Is >> ......;
    return is;
  }
};

输出没问题:

my_ostream << Wrap{some_string};

因为将 temp Wrap 绑定到 const ref 是可以的。

但输入不太好:

my_istream >> Wrap{some_string}; // doesn't compile - cannot bind lvalue to rvalue

我可能会构建它,但由于我没有看到任何&gt;&gt; &amp;&amp;,所以感觉有些不对劲。

&gt;&gt;&amp;&amp; 在某种程度上是被禁止的还是邪恶的?

【问题讨论】:

  • 不相关,os &gt;&gt; ...... - 很确定你的意思是os &lt;&lt; ......
  • 你为什么要通过电话发布非常技术性的问题?
  • 这是用什么工具链?我问是因为,除非我没有看到眼前的东西,clang has no problems with this
  • @Michał 是的,我是那个打勾的。

标签: c++ c++14 rvalue


【解决方案1】:

(在 gcc 版本 7.3.0(Ubuntu 7.3.0-16ubuntu3)上测试)

您的代码按原样运行(在此处运行:http://cpp.sh/9tk5k):

#include <string>
#include <iostream>


struct Wrap {
  std::string& s; // need const ref for output, non const for input 
  friend std::ostream& operator<< (std::ostream& os, const Wrap& w) {
    os << "[" << w.s << "]";
    return os;
  }
  friend std::istream& operator>> (std::istream& is, Wrap&& w) {
    is >> w.s;
    return is;
  }
};


int main() {
    std::string a = "abcd";
    std::cin >> Wrap{a};
    std::cout << Wrap{a};
}

您应该能够将 Wrap 作为 r 值传递。如果您是在线创建它,那正是发生的情况。

将 r 值绑定到 const ref 应该(并且确实)也可以工作。

【讨论】:

  • FWIW 您也可以在operator&gt;&gt;(和operator&lt;&lt;)中按值获取Wrap 对象,然后它可以在左值和右值上工作。字符串引用始终是非常量的,因此Wrap 参数的常量无关紧要。
  • 在写的情况下。我通过 Wrap a cost string&... 让事情变得不同
【解决方案2】:

右值引用只能绑定到右值。大多数时候,这就是您想要的——它确保(例如)当您编写移动 ctor/赋值运算符时,您不会意外地在左值上调用它,并破坏仍将被使用的东西。

我不确定为什么在这种情况下你要使用右值引用,但你确实需要它是有原因的,当它是模板参数时,你至少可以使用相同的语法:

struct Wrap
{
    std::string s; // need const ref for output, non const for input
    friend std::ostream &operator<<(std::ostream &os, const Wrap &w)
    {
        os << "[" << w.s << "]";
        return os;
    }

    template <class T>
    friend std::istream &operator>>(std::istream &is, T &&w)
    {
        is >> w.s;
        return is;
    }
};

int main() {
    int x;

    Wrap w;

    std::cin >> w;
}

不确定这是否真的有用。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-02-12
    • 1970-01-01
    • 2021-12-12
    • 1970-01-01
    • 1970-01-01
    • 2011-03-17
    • 2018-07-21
    • 2013-01-04
    相关资源
    最近更新 更多