为什么没有istream支持rvalue提取

问题描述 投票:-1回答:2

我有一个包围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

我可能会建立它,但因为我没有看到任何>> &&一些感觉不对。

>>&&在某种程度上被禁止或邪恶吗?

c++ c++14 rvalue
2个回答
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应该(并且确实)也可以。


0
投票

右值引用只能绑定到右值。大多数情况下,这就是你想要的 - 它确保(例如)当你编写一个移动ctor /赋值操作符时,你不会意外地在一个左值上调用它,并且破坏仍然会被使用的东西。

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

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;
}

不确定这是否真的有用。

© www.soinside.com 2019 - 2024. All rights reserved.