оператор << не может вывести std :: endl - исправить? - PullRequest
4 голосов
/ 10 апреля 2010

Следующий код выдает ошибку, когда предполагается вывести только 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 Ответ

8 голосов
/ 10 апреля 2010

Вы должны добавить это к вашему 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...