mycout automatic endl

只谈情不闲聊 提交于 2019-12-18 16:12:23

问题


I'd like implement class MyCout, which can provide possibility of automatic endl, i.e. this code

MyCout mycout;
mycout<<1<<2<<3;

outputs

123
//empty line here

Is it possible to implement class with such functionality?


UPDATE: Soulutions shouldn't be like that MyCout()<<1<<2<<3; i.e. they should be without creating temporary object


回答1:


This is simply a variant of Rob's answer, that doesn't use the heap. It's a big enough change that I didn't want to just change his answer though

struct MyCout {
  MyCout(std::ostream& os = std::cout) : os(os) {}
  struct A {
    A(std::ostream& r) : os(r), live(true) {}
    A(A& r) : os(r.os), live(true) {r.live=false;}
    A(A&& r) : os(r.os), live(true) {r.live=false;}
    ~A() { if(live) {os << std::endl;} }
    std::ostream& os;
    bool live;
  };
  std::ostream& os;
};

template <class T>
MyCout::A operator<<(MyCout::A&& a, const T& t) {
  a.os << t;
  return a;
}

template<class T>
MyCout::A operator<<(MyCout& m, const T& t) { return MyCout::A(m.os) << t; }

int main () {
  MyCout mycout;
  mycout << 1 << 2.0 << '3';
  mycout << 3 << 4.0 << '5';
  MyCout mycerr(std::cerr);
  mycerr << 6 << "Hello, world" << "!";
}



回答2:


You can use the destructor of a temporary object to flush the stream and print a newline. The Qt debug system does this, and this answer describes how to do it.




回答3:


The following works in C++11:

#include <iostream>

struct myout_base { };
struct myout
{
  bool alive;
  myout() : alive(true) { }
  myout(myout && rhs) : alive(true) { rhs.alive = false; }
  myout(myout const &) = delete;
  ~myout() { if (alive) std::cout << std::endl; }
};

template <typename T>
myout operator<<(myout && o, T const & x)
{
  std::cout << x;
  return std::move(o);
}

template <typename T>
myout operator<<(myout_base &, T const & x)
{
  return std::move(myout() << x);
}

myout_base m_out;   // like the global std::cout

int main()
{
  m_out << 1 << 2 << 3;
}

With more work, you can add a reference to the actual output stream.




回答4:


If you need to avoid C++11 features:

#include <iostream>
#include <sstream>
#include <memory>

struct MyCout {
  MyCout(std::ostream& os = std::cout) : os(os) {}
  struct A {
    A(std::ostream& os) : os(os) {}
    A() : os(os) {}
    ~A() { os << std::endl; }
    std::ostream& os;
  };
  std::ostream& os;
};

template <class T>
const std::auto_ptr<MyCout::A>&
operator<<(const std::auto_ptr<MyCout::A>& a, const T& t) {
  a->os << t;
  return a;
}

template<class T>
const std::auto_ptr<MyCout::A>
operator<<(MyCout& m, const T& t) {
  std::auto_ptr<MyCout::A> p(new MyCout::A(m.os));
  p << t;
  return p;
}

int main () {
  MyCout mycout;
  mycout << 1 << 2 << 3;
  mycout << 3 << 4 << 5;
  MyCout mycerr(std::cerr);
  mycerr << 6 << "Hello, world" << "!";
}


来源:https://stackoverflow.com/questions/8510071/mycout-automatic-endl

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!