运营商LT;<无法输出std :: endl - 修复?

时间:2010-04-10 03:23:53

标签: c++ templates stl operator-overloading

以下代码在应该仅输出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<<定义要求输入字符串。

模仿operator<<没有帮助:

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

如何使代码有效?谢谢!

1 个答案:

答案 0 :(得分:8)

您需要将其添加到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";
  }

将正确输出

start
done