【问题标题】:Parameter of type "has << operator"“具有 << 运算符”类型的参数
【发布时间】:2013-06-13 14:32:37
【问题描述】:

我需要在输出流上绘制我的对象,通常是cout。 但我也希望用户能够输入任何具有&lt;&lt; 运算符的流(例如QTextStream),因此不必每次都输入cout。 定义此类参数的最简单方法是什么?

所以这就是我想要的,可以编译的东西:

virtual void draw(GeneralOutStream out = std::cout)
{
    out <<  m_name << std::endl;
}

我知道我可以使用模板,(这就是我正在做的 atm。) 但我希望有一个不需要模板的解决方案。 但是,模板解决方案工作正常,所以基本上我只是好奇。

【问题讨论】:

  • 如果您的对象继承自 std::ostream,您可以通过引用传递它。如果没有,我会使用模板。除非您的对象真的是流,否则我也不会添加此依赖项。
  • 我会选择模板。只有在代码中某处使用该类型时,它们才会编译为特定类型。您甚至可以为不支持 &lt;&lt; 运算符的用户提供专用版本。所以这是一个更好的解决方案 IMO。
  • 如果您想支持 any 流,则需要模板,因为流本身是模板化的。我们是成熟行业的认真工程师,我们有广泛的字符和流来支持世界的语言!有时甚至可以使用它们,令我们惊讶的是......
  • 然而,虚拟模板并不存在,因此您的解决方案的工作原理并不完全清楚。
  • 这里使用模板没有意义; std::ostream&amp; 应该够了。

标签: c++ io stream iostream


【解决方案1】:

我能想到四种方法。

首先,将std::ostream 作为您的GeneralOutStream,并假设每个人都继承它。也许写一些东西来包装QTextStream,使其成为std::ostream

其次,编写一个template 方法,接受GeneralOutStream&amp;&amp; out 并对其进行操作。这需要在您的标头中公开您的实现。我会推荐这个。非常强烈,但这确实意味着virtual 最终变得毫无用处。

第三,编写一个类型擦除GeneralOutStream,使用template 构造函数公开您希望在类中与之交互的一般输出流的部分,该构造函数将传入的泛型类型存储在pImpl 和@987654331 中@ 方法,然后在对象的实现中使用该类型。这具有运行时开销并且编写起来非常棘手,并且类似于 std::function 的模式——除了 GeneralOutStream 必须处理能够编写大量类型的能力!

如果我要编写#3,GeneralOutStream 将是一个template,它采用GeneralOutStream 应该处理的一系列类型,然后进行一些元编程以将这些重载准确地暴露给&lt;&lt;。这变得非常棘手,因为您需要手动复制重载决议。

第四,创建一个您想要支持的“GeneralOutStream”类型的枚举。使用双分派技术通过virtual 方法调用传递对这些类型实例的引用,在另一端解绑它们并调用您的实现template 方法,要求实现类处理整个枚举。这个实现比#3 稍微简单一些,限制了可以传递给draw 方法的类型,但允许在实现class 中完全访问该类型。

【讨论】:

  • 我将不得不对这些进行一些尝试,但我想我会选择第二种解决方案.. :P 谢谢
【解决方案2】:

您想要任何(派生自std::ostream)或具有&lt;&lt; 运算符的任何 对象的解决方案?

在第一种情况下,您可以传递对流对象的引用:

virtual void draw(std::ostream& out = cout) {
    out << m_name << std::endl;
}

传递副本不会编译。

在第二种情况下,主要问题是接口,因为看起来您想将该函数定义为虚拟成员。如果不是这种情况,并且您仍然想要 any 对象的解决方案(不是必需的标准 ostream,但任何定义了运算符 &lt;&lt; 的对象),您将不得不使用模板。

【讨论】:

  • @n.m.:我知道。当我说“你必须使用模板”时,我指的是第二种情况:任何支持运算符 &lt;&lt; 的对象,当然,没有虚拟要求。我已经编辑了答案以使其更清晰。 (如果我的答案仍然不清楚,请告诉我)。
猜你喜欢
  • 2011-11-13
  • 1970-01-01
  • 1970-01-01
  • 2015-03-27
  • 1970-01-01
  • 1970-01-01
  • 2015-05-24
  • 2018-03-29
  • 2016-08-30
相关资源
最近更新 更多