【问题标题】:operator<< cannot output std::endl -- Fix?operator<< 不能输出 std::endl -- 修复?
【发布时间】:2011-02-06 09:56:39
【问题描述】:

以下代码在应该只输出std::endl 时给出错误:

#include <iostream>
#include <sstream>

struct MyStream {
  std::ostream* out_;
  MyStream(std::ostream* out) : out_(out) {}
  std::ostream& operator<<(const std::string& s) {
    (*out_) << s;
    return *out_;
  }
};

template<class OutputStream>
struct Foo {
  OutputStream* out_;
  Foo(OutputStream* out) : out_(out) {}
  void test() {
    (*out_) << "OK" << std::endl;
    (*out_) << std::endl; // ERROR     
  }
};

int main(int argc, char** argv){
  MyStream out(&std::cout);
  Foo<MyStream> foo(&out);
  foo.test();
  return EXIT_SUCCESS;
}

错误是:

stream1.cpp:19: error: no match for 'operator<<' in '*((Foo<MyStream>*)this)->Foo<MyStream>::out_ << std::endl'
stream1.cpp:7: note: candidates are: std::ostream& MyStream::operator<<(const std::string&)

所以它可以输出一个字符串(见错误上面那行),但不仅仅是std::endl,大概是因为std::endl不是字符串,而是operator&lt;&lt;定义要求的是字符串。

模板化 operator&lt;&lt; 没有帮助:

  template<class T>
  std::ostream& operator<<(const T& s) { ... }

我怎样才能使代码工作?谢谢!

【问题讨论】:

    标签: c++ templates stl operator-overloading


    【解决方案1】:

    您需要将此添加到您的struct MyStream

      std::ostream& operator<<( std::ostream& (*f)(std::ostream&) )
      {
          return f(*out_);
      }
    

    std::endl 是一个附加换行符并刷新底层流的函数;此函数签名接受该函数并将其应用于ostream 成员。

    然后,作为测试,将foo::test 定义为

      void test() {
        (*out_) << "start";
        (*out_) << std::endl;
        (*out_) << "done";
      }
    

    会正确输出

    开始 完毕

    【讨论】:

    • 谢谢,这太疯狂了。一个人应该怎么知道?应该有一些可以派生的类会自动添加这些难看的东西。
    • 重载 iostream 运算符要记住的是 const char* 和这个函数指针。这是因为 C++ 模板系统有一些关于指针类型的特殊规则。 (我认为它们是模棱两可的?)
    • @dehmann:我知道人们应该怎么知道这一点。我必须尝试几个不同的 Google 搜索才能指出正确的方向,然后我仍然必须拼凑答案。希望这可以帮助更多处于这种情况的人。
    • 它不是一个函数,而是一个函数模板(因此它不是特定于ostream,但也适用于wostream 和其他)。这就是为什么简单的T 不起作用的原因。
    猜你喜欢
    • 2015-09-17
    • 2013-01-27
    • 2020-07-23
    • 2010-11-11
    • 2018-03-02
    • 1970-01-01
    • 2015-08-13
    • 2017-05-31
    相关资源
    最近更新 更多