【问题标题】:C++ function that returns an ostream返回 ostream 的 C++ 函数
【发布时间】:2020-08-07 16:38:26
【问题描述】:

我有许多 operator<<() 函数,它们从做类似的事情开始,所以我想抽象一下。这是我正在尝试做的最小可重复案例(消除了所有复杂性)。请注意,它不会编译。如果它确实编译了,我希望程序自己在一行上打印数字 3。

/*                                                                                                   
  clang++ -std=c++14 -Wall -Wextra foo.cc -o foo                                                     
*/

#include <ostream>
#include <iostream>

using std::cout;
using std::endl;
using std::ostream;

ostream& BaseFunction(ostream& os, const int x) {
  return os << x;
}

int main(int argc, char *argv[]) {
  cout << BaseFunction(cout, 3) << endl;
}

错误是这样开始的:

foo.cc:17:8: error: invalid operands to binary expression ('ostream' (aka 'basic_ostream<char>') and
      'ostream')
  cout << BaseFunction(cout, 3) << endl;
  ~~~~ ^  ~~~~~~~~~~~~~~~~~~~~~

然后提供一大堆“从 ostream 到 T 的未知转换”建议。

有人知道我做错了什么吗?

【问题讨论】:

  • 取出BaseFunction(cout, 3) &lt;&lt; endl;中的cout,它应该可以工作。
  • 我不确定你的目标是什么,但也许你想要this pattern
  • 聪明的解决方法@MooingDuck,谢谢!

标签: c++ c++14 ostream


【解决方案1】:

Basefunction(cout, 3) 返回cout

因此,最后一行等价于

cout << 3;
cout << cout << endl;

由于cout &lt;&lt; cout 没有意义,因此您会收到错误消息。

【讨论】:

  • 谢谢,完全正确。我正在复制我对operator&lt;&lt;() 所做的事情,并错过了覆盖如何使其全部工作的重要细节。我接受了@blindy 的回复,只是因为在第一次阅读时,那是我点击的那个。
【解决方案2】:

您为此使用了一种非常奇怪和独特(即糟糕)的模式,使用它的方式是:

BaseFunction(cout, 3) << endl;

请注意,您将输入流作为参数传递给函数,并且由于您将流作为输出返回,并且没有operator&lt;&lt; 的重载同时在左侧和右侧接收流,使用 C++ 流的常规方式在这里不起作用。

完成此操作的通常方法是添加一个operator&lt;&lt; 重载,该重载采用左侧流和右侧自定义对象,并执行您需要执行的任何操作来显示您的对象。在您的情况下,将函数替换为不将流作为参数并返回自定义对象的函数,然后您可以使用该对象重载流操作符。

【讨论】:

  • 谢谢。该模式很奇怪,因为我正在复制operator&lt;&lt;() 模式,并且错过了覆盖如何使其全部工作的重要细节。感谢您如此详细地解释它。
【解决方案3】:

您所做的实际上是定义一个自定义流操纵器。可以改为这样实现:

/* clang++ -std=c++14 -Wall -Wextra foo.cc -o foo */

#include <iostream>
using std::cout;
using std::endl;
using std::ostream;

struct myValue {
    int value;
};

myValue BaseFunction(const int x) {
    return myValue{x};
}

ostream& operator<<(ostream &os, const myValue &v) {
    return os << v.value;
}

int main(int argc, char *argv[]) {
    cout << BaseFunction(3) << endl;
}

Live Demo

【讨论】:

    【解决方案4】:

    你可以试试这个:

    BaseFunction(cout, 3);
    cout << endl;
    
    

    我认为 ostream 不能输出 ostream。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-10-31
      • 1970-01-01
      • 2015-10-01
      相关资源
      最近更新 更多