移动 std::istream

Moving std::istream

提问人:Touloudou 提问时间:4/1/2020 更新时间:4/1/2020 访问量:1249

问:

我有一个类来标记来自文件等的字符流。Scannercin

class Scanner {
public:
  Scanner(std::istream&& c) : input{std::move(c)} {}

private:
  std::istream input;
};

此代码不编译,因为 的移动构造函数受保护。我可以改用对流的引用,但是,我不能保证有人不会在类外玩我的流(如下)。std::istreamScannerss

  std::string code = "this is code";
  std::stringstream ss{code};
  Scanner scanner{ss};

有没有一种巧妙的方法来解决这个问题,或者人们只是使用并希望得到最好的结果?std::istream&

C++ 移动 Fstream IOstream iStream

评论

0赞 Vivick 4/1/2020
我认为没有任何理由拥有流的所有权
0赞 0xbaadf00d 4/1/2020
好吧,你不能使用 std::istream&。该对象将不存。
0赞 WhozCraig 4/1/2020
如果要移动流,请移动流,而不是通过抽象基类进行某些引用。您可以移动具体对象本身(在本例中为 )。但是试图移动抽象基类引用是无稽之谈。这不是移动的工作方式。如果 是 ,并且参数是 ,你的代码会更快乐。std::istringsreaminputstd::istringstreamstd::istringstream&& c
0赞 Touloudou 4/1/2020
是的,但我试图获得一个也适用于 std::ifstream、cin 等的扫描仪。如果我将输入更改为 std::istringstream,那将不再有效。
0赞 0xbaadf00d 4/1/2020
@WhozCraig 但这不是他在这里想要实现的目标。

答:

0赞 0xbaadf00d 4/1/2020 #1

从我所记得的关于我使用流对象的工作来看。

你需要以不同的方式思考这个问题。

class Scanner {
public:
  Scanner() {}
  virtual void scan(std::istream & p_stream);
};

你的 Scanner 类可能只专注于扫描输入中的任何内容,而不是实际包含它。

现在,它可以完全专注于单个任务。

然后,您需要找出保持流对象活动的最佳方法。我建议为该任务设置一个单独的课程。

我本来会把这个写成评论,但这里太多了。

评论

0赞 Touloudou 4/1/2020
是的,这是B计划。我只是对参考不满意。谢谢。但是,为什么是虚拟功能?
0赞 0xbaadf00d 4/1/2020
啊,只是事后的想法。你可能想制作多个不同的扫描仪,以寻找不同的东西。然后是一个包含所有这些扫描仪的扫描仪,并按顺序运行它们或其他东西。(寻找多个东西)
0赞 0xbaadf00d 4/1/2020
除了您自己的自定义逻辑扫描器之外,您可能还想制作一个正则表达式扫描器(将正则表达式作为参数?)和 XML 扫描器。但也许这对你正在做的事情来说太过分了。
0赞 0xbaadf00d 4/1/2020
去看看“复合设计模式”。我很确定互联网有比我更好的解释。