【问题标题】:Moving std::istream移动 std::istream
【发布时间】:2020-07-13 00:19:36
【问题描述】:

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

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

private:
  std::istream input;
};

此代码无法编译,因为std::istream 的移动构造函数受到保护。我可以使用对流的引用,但是,我不能保证有人没有在Scanner 类(下面的ss)之外玩我的流。

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

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

【问题讨论】:

  • 我认为没有任何理由获得流的所有权
  • 好吧,你不能使用 std::istream&。该对象将无法生存。
  • 如果你想移动流,那么移动流,而不是通过抽象基类的一些引用。您可以移动具体对象本身(在本例中为std::istringsream)。但是试图移动一个抽象的基类引用是无稽之谈。这不是移动的工作原理。如果inputstd::istringstream,并且参数是std::istringstream&& c,你的代码会更快乐。
  • 是的,但我试图获得一个也适用于 std::ifstream、cin 等的扫描仪。如果我将输入更改为 std::istringstream,则不再适用。
  • @WhozCraig 但这不是他想要在这里实现的目标。

标签: c++ move fstream iostream istream


【解决方案1】:

根据我对流对象工作的记忆。

你需要换个角度思考这个问题。

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

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

现在它可以只专注于一项任务。

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

我会写这个作为评论,但是这里太多了。

【讨论】:

  • 是的,这是 B 计划。我只是对引用不满意。不过谢谢。但是,为什么是虚函数呢?
  • 啊,只是事后的想法。您可能想要制作多个不同的扫描仪,以寻找不同的东西。然后是一个包含所有这些扫描仪并按顺序运行它们的扫描仪。 (寻找多个东西)
  • 除了您自己的自定义逻辑扫描器之外,您可能还想制作一个正则表达式扫描器(将正则表达式作为参数?)和一个 XML 扫描器。但也许这对你所做的来说太过分了。
  • 去看看“复合设计模式”。我很确定互联网上有比我更好的解释。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-07-12
  • 2017-01-16
  • 2010-12-21
  • 2014-08-29
  • 1970-01-01
  • 2012-01-01
相关资源
最近更新 更多