null ostream?

Discussion in 'C++' started by Angel Tsankov, Nov 23, 2005.

  1. How do I define a null ostream that inherits publicly std::eek:stream and
    ignores anything that would otherwise be output?
    Angel Tsankov, Nov 23, 2005
    #1
    1. Advertising

  2. Angel Tsankov

    Mark P Guest

    Angel Tsankov wrote:
    > How do I define a null ostream that inherits publicly std::eek:stream and
    > ignores anything that would otherwise be output?
    >


    You could create an ofstream that writes to /dev/null
    Not portable, but easy :)
    Mark P, Nov 23, 2005
    #2
    1. Advertising

  3. Angel Tsankov wrote:

    > How do I define a null ostream that inherits publicly std::eek:stream and
    > ignores anything that would otherwise be output?


    I cribbed this from c.l.c++ years ago - don't remember the original
    author (but it's not me):

    #include <streambuf>
    #include <ostream>

    template <class cT, class traits = std::char_traits<cT> >
    class basic_nullbuf: public std::basic_streambuf<cT, traits> {
    typename traits::int_type overflow(typename traits::int_type c)
    {
    return traits::not_eof(c); // indicate success
    }
    };

    template <class cT, class traits = std::char_traits<cT> >
    class basic_onullstream: public std::basic_ostream<cT, traits> {
    public:
    basic_onullstream():
    std::basic_ios<cT, traits>(&m_sbuf),
    std::basic_ostream<cT, traits>(&m_sbuf)
    {
    init(&m_sbuf);
    }

    private:
    basic_nullbuf<cT, traits> m_sbuf;
    };

    typedef basic_onullstream<char> onullstream;
    typedef basic_onullstream<wchar_t> wonullstream;

    Best regards,

    Tom
    Thomas Tutone, Nov 23, 2005
    #3
  4. try this:

    #include <iostream>

    struct null_streambuf
    : public std::streambuf
    {
    void overflow(char c)
    {
    }
    };

    int main()
    {
    null_streambuf nullbuf;

    // replace buffer of existing stream
    std::streambuf * origbuf = std::cout.rdbuf(&nullbuf);
    std::cout << "this goes into oblivion";
    std::cout.rdbuf(origbuf);

    // create null ostream
    std::eek:stream out(&nullbuf);
    out << "this goes into oblivion too...";
    }


    -- peter
    peter steiner, Nov 23, 2005
    #4
  5. to correct myself, Thomas Tutone's version's author hasn't been too
    lazy to ignore non-char character traits and the proper return value of
    the streambuf::eek:verflow member. use that one. :)
    peter steiner, Nov 23, 2005
    #5
  6. "Thomas Tutone" <> wrote in message
    news:...
    > Angel Tsankov wrote:
    >
    >> How do I define a null ostream that inherits publicly std::eek:stream
    >> and
    >> ignores anything that would otherwise be output?

    >
    > I cribbed this from c.l.c++ years ago - don't remember the original
    > author (but it's not me):
    >
    > #include <streambuf>
    > #include <ostream>
    >
    > template <class cT, class traits = std::char_traits<cT> >
    > class basic_nullbuf: public std::basic_streambuf<cT, traits> {
    > typename traits::int_type overflow(typename traits::int_type c)
    > {
    > return traits::not_eof(c); // indicate success
    > }
    > };
    >
    > template <class cT, class traits = std::char_traits<cT> >
    > class basic_onullstream: public std::basic_ostream<cT, traits> {
    > public:
    > basic_onullstream():
    > std::basic_ios<cT, traits>(&m_sbuf),
    > std::basic_ostream<cT, traits>(&m_sbuf)
    > {
    > init(&m_sbuf);
    > }
    >
    > private:
    > basic_nullbuf<cT, traits> m_sbuf;
    > };
    >
    > typedef basic_onullstream<char> onullstream;
    > typedef basic_onullstream<wchar_t> wonullstream;
    >
    > Best regards,
    >
    > Tom
    >


    Thanks, Tom! This seems to be exactly what I need:)
    Angel Tsankov, Nov 24, 2005
    #6
  7. "Thomas Tutone" <> wrote in message
    news:...
    > Angel Tsankov wrote:
    >
    >> How do I define a null ostream that inherits publicly std::eek:stream
    >> and
    >> ignores anything that would otherwise be output?

    >
    > I cribbed this from c.l.c++ years ago - don't remember the original
    > author (but it's not me):
    >
    > #include <streambuf>
    > #include <ostream>
    >
    > template <class cT, class traits = std::char_traits<cT> >
    > class basic_nullbuf: public std::basic_streambuf<cT, traits> {
    > typename traits::int_type overflow(typename traits::int_type c)
    > {
    > return traits::not_eof(c); // indicate success
    > }
    > };
    >
    > template <class cT, class traits = std::char_traits<cT> >
    > class basic_onullstream: public std::basic_ostream<cT, traits> {
    > public:
    > basic_onullstream():
    > std::basic_ios<cT, traits>(&m_sbuf),
    > std::basic_ostream<cT, traits>(&m_sbuf)
    > {
    > init(&m_sbuf);
    > }
    >
    > private:
    > basic_nullbuf<cT, traits> m_sbuf;
    > };
    >
    > typedef basic_onullstream<char> onullstream;
    > typedef basic_onullstream<wchar_t> wonullstream;
    >
    > Best regards,
    >
    > Tom
    >


    May I save the call init(&m_sbuf); in basic_onullstream's ctor as this
    same call is made in basic_ostream's ctor?
    Angel Tsankov, Nov 24, 2005
    #7
  8. Angel Tsankov wrote:
    >
    > "Thomas Tutone" <> wrote in message
    > news:...
    >
    >> Angel Tsankov wrote:
    >>
    >>> How do I define a null ostream that inherits publicly std::eek:stream and
    >>> ignores anything that would otherwise be output?

    >>
    >>
    >> I cribbed this from c.l.c++ years ago - don't remember the original
    >> author (but it's not me):
    >>
    >> #include <streambuf>
    >> #include <ostream>
    >>
    >> template <class cT, class traits = std::char_traits<cT> >
    >> class basic_nullbuf: public std::basic_streambuf<cT, traits> {
    >> typename traits::int_type overflow(typename traits::int_type c)
    >> {
    >> return traits::not_eof(c); // indicate success
    >> }
    >> };
    >>
    >> template <class cT, class traits = std::char_traits<cT> >
    >> class basic_onullstream: public std::basic_ostream<cT, traits> {
    >> public:
    >> basic_onullstream():
    >> std::basic_ios<cT, traits>(&m_sbuf),
    >> std::basic_ostream<cT, traits>(&m_sbuf)
    >> {
    >> init(&m_sbuf);
    >> }
    >>
    >> private:
    >> basic_nullbuf<cT, traits> m_sbuf;
    >> };
    >>
    >> typedef basic_onullstream<char> onullstream;
    >> typedef basic_onullstream<wchar_t> wonullstream;
    >>
    >> Best regards,
    >>
    >> Tom
    >>

    >
    > May I save the call init(&m_sbuf); in basic_onullstream's ctor as this
    > same call is made in basic_ostream's ctor?


    My preference would be to keep init and change the initialiser list

    basic_onullstream()
    {
    init(&m_sbuf);
    }

    john
    John Harrison, Nov 24, 2005
    #8
  9. "John Harrison" <> wrote in message
    news:yNehf.361$...
    > Angel Tsankov wrote:
    >>
    >> "Thomas Tutone" <> wrote in message
    >> news:...
    >>
    >>> Angel Tsankov wrote:
    >>>
    >>>> How do I define a null ostream that inherits publicly
    >>>> std::eek:stream and
    >>>> ignores anything that would otherwise be output?
    >>>
    >>>
    >>> I cribbed this from c.l.c++ years ago - don't remember the
    >>> original
    >>> author (but it's not me):
    >>>
    >>> #include <streambuf>
    >>> #include <ostream>
    >>>
    >>> template <class cT, class traits = std::char_traits<cT> >
    >>> class basic_nullbuf: public std::basic_streambuf<cT, traits> {
    >>> typename traits::int_type overflow(typename traits::int_type c)
    >>> {
    >>> return traits::not_eof(c); // indicate success
    >>> }
    >>> };
    >>>
    >>> template <class cT, class traits = std::char_traits<cT> >
    >>> class basic_onullstream: public std::basic_ostream<cT, traits> {
    >>> public:
    >>> basic_onullstream():
    >>> std::basic_ios<cT, traits>(&m_sbuf),
    >>> std::basic_ostream<cT, traits>(&m_sbuf)
    >>> {
    >>> init(&m_sbuf);
    >>> }
    >>>
    >>> private:
    >>> basic_nullbuf<cT, traits> m_sbuf;
    >>> };
    >>>
    >>> typedef basic_onullstream<char> onullstream;
    >>> typedef basic_onullstream<wchar_t> wonullstream;
    >>>
    >>> Best regards,
    >>>
    >>> Tom
    >>>

    >>
    >> May I save the call init(&m_sbuf); in basic_onullstream's ctor as
    >> this same call is made in basic_ostream's ctor?

    >
    > My preference would be to keep init and change the initialiser list
    >
    > basic_onullstream()
    > {
    > init(&m_sbuf);
    > }
    >
    > john


    Well, I'm not sure this is a good idea, as ctors of virtual bases must
    be called by any derived class ctor, right?
    Angel Tsankov, Nov 24, 2005
    #9
  10. Angel Tsankov wrote:
    > How do I define a null ostream that inherits publicly std::eek:stream and
    > ignores anything that would otherwise be output?


    You can just set the failbit on any ostream. This makes it effectively
    ignore all output sent to it until you unset the bit.
    Maxim Yegorushkin, Nov 24, 2005
    #10
  11. Angel Tsankov wrote:
    >
    > "John Harrison" <> wrote in message
    > news:yNehf.361$...
    >
    >> Angel Tsankov wrote:
    >>
    >>>
    >>> "Thomas Tutone" <> wrote in message
    >>> news:...
    >>>
    >>>> Angel Tsankov wrote:
    >>>>
    >>>>> How do I define a null ostream that inherits publicly std::eek:stream and
    >>>>> ignores anything that would otherwise be output?
    >>>>
    >>>>
    >>>>
    >>>> I cribbed this from c.l.c++ years ago - don't remember the original
    >>>> author (but it's not me):
    >>>>
    >>>> #include <streambuf>
    >>>> #include <ostream>
    >>>>
    >>>> template <class cT, class traits = std::char_traits<cT> >
    >>>> class basic_nullbuf: public std::basic_streambuf<cT, traits> {
    >>>> typename traits::int_type overflow(typename traits::int_type c)
    >>>> {
    >>>> return traits::not_eof(c); // indicate success
    >>>> }
    >>>> };
    >>>>
    >>>> template <class cT, class traits = std::char_traits<cT> >
    >>>> class basic_onullstream: public std::basic_ostream<cT, traits> {
    >>>> public:
    >>>> basic_onullstream():
    >>>> std::basic_ios<cT, traits>(&m_sbuf),
    >>>> std::basic_ostream<cT, traits>(&m_sbuf)
    >>>> {
    >>>> init(&m_sbuf);
    >>>> }
    >>>>
    >>>> private:
    >>>> basic_nullbuf<cT, traits> m_sbuf;
    >>>> };
    >>>>
    >>>> typedef basic_onullstream<char> onullstream;
    >>>> typedef basic_onullstream<wchar_t> wonullstream;
    >>>>
    >>>> Best regards,
    >>>>
    >>>> Tom
    >>>>
    >>>
    >>> May I save the call init(&m_sbuf); in basic_onullstream's ctor as
    >>> this same call is made in basic_ostream's ctor?

    >>
    >>
    >> My preference would be to keep init and change the initialiser list
    >>
    >> basic_onullstream()
    >> {
    >> init(&m_sbuf);
    >> }
    >>
    >> john

    >
    >
    > Well, I'm not sure this is a good idea, as ctors of virtual bases must
    > be called by any derived class ctor, right?


    Right, but the code above is exactly equivalent to this

    basic_onullstream() : std::basic_ios<cT, traits>()
    {
    init(&m_sbuf);
    }

    in other words the default constructor of the virtual base class will be
    called automatically if you don't explicitly specify a different
    constructor.

    john
    John Harrison, Nov 24, 2005
    #11
  12. >>>>
    >>>> May I save the call init(&m_sbuf); in basic_onullstream's ctor as
    >>>> this same call is made in basic_ostream's ctor?
    >>>
    >>>
    >>> My preference would be to keep init and change the initialiser
    >>> list
    >>>
    >>> basic_onullstream()
    >>> {
    >>> init(&m_sbuf);
    >>> }
    >>>
    >>> john

    >>
    >>
    >> Well, I'm not sure this is a good idea, as ctors of virtual bases
    >> must be called by any derived class ctor, right?

    >
    > Right, but the code above is exactly equivalent to this
    >
    > basic_onullstream() : std::basic_ios<cT, traits>()
    > {
    > init(&m_sbuf);
    > }
    >
    > in other words the default constructor of the virtual base class
    > will be called automatically if you don't explicitly specify a
    > different constructor.
    >
    > john


    Yes, I totally agree with you on this point. Anyway, could tou tell us
    the reasons you prefer to change the initializer list but keep init?
    Angel Tsankov, Nov 24, 2005
    #12
  13. >
    > Yes, I totally agree with you on this point. Anyway, could tou tell us
    > the reasons you prefer to change the initializer list but keep init?


    Nothing deep, it's just when I write code like this

    template <class cT, class traits = std::char_traits<cT> >
    class basic_onullstream: public std::basic_ostream<cT, traits> {
    public:
    basic_onullstream():
    std::basic_ios<cT, traits>(&m_sbuf),
    std::basic_ostream<cT, traits>(&m_sbuf)
    {
    }

    my compiler warns me about using pointers to as yet unconstructed
    objects. If the basic_ios or basic_ostream constructors were to
    dereference the pointer it would be undefined behaviour. They don't of
    course but my compiler doesn't know that so I get the warning.

    john
    John Harrison, Nov 24, 2005
    #13
  14. >>
    >> Yes, I totally agree with you on this point. Anyway, could tou tell
    >> us the reasons you prefer to change the initializer list but keep
    >> init?

    >
    > Nothing deep, it's just when I write code like this
    >
    > template <class cT, class traits = std::char_traits<cT> >
    > class basic_onullstream: public std::basic_ostream<cT, traits> {
    > public:
    > basic_onullstream():
    > std::basic_ios<cT, traits>(&m_sbuf),
    > std::basic_ostream<cT, traits>(&m_sbuf)
    > {
    > }
    >
    > my compiler warns me about using pointers to as yet unconstructed
    > objects. If the basic_ios or basic_ostream constructors were to
    > dereference the pointer it would be undefined behaviour. They don't
    > of course but my compiler doesn't know that so I get the warning.
    >
    > john


    What compiler are you using?
    Angel Tsankov, Nov 27, 2005
    #14
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Replies:
    5
    Views:
    26,434
    Mike Schilling
    Mar 29, 2006
  2. Alex Dribin

    Line wrapping in ostream

    Alex Dribin, Aug 6, 2003, in forum: C++
    Replies:
    2
    Views:
    346
    Dietmar Kuehl
    Aug 6, 2003
  3. Parity
    Replies:
    2
    Views:
    353
    Stephen Howe
    Aug 13, 2003
  4. Bo Peng
    Replies:
    13
    Views:
    13,251
    Siemel Naran
    Jul 18, 2004
  5. Replies:
    2
    Views:
    1,879
Loading...

Share This Page