ostringstream and write()

Discussion in 'C++' started by roberts.noah@gmail.com, Jan 30, 2006.

  1. Guest

    Using ostringstream the buffer gets increased to allow data to be
    appended when needed at least when you call <<. I was under the
    impression that write() also did but I am having problems that make me
    doubt that. Can I depend on the behavior of something like this?

    ostringstream os;

    os.write("This is a test.", strlen("This is a test."));
    cout << os.str() << endl;

    If so my problem is obviously caused by something else...
    , Jan 30, 2006
    #1
    1. Advertising

  2. Guest

    wrote:
    > Using ostringstream the buffer gets increased to allow data to be
    > appended when needed at least when you call <<. I was under the
    > impression that write() also did but I am having problems that make me
    > doubt that. Can I depend on the behavior of something like this?
    >
    > ostringstream os;
    >
    > os.write("This is a test.", strlen("This is a test."));
    > cout << os.str() << endl;
    >
    > If so my problem is obviously caused by something else...


    I realized what the problem was. I was using iostream as a polymorphic
    entity and it isn't. Code above would have looked more like this
    logically invalid code:

    ostringstream os;
    ostream * ptr = &os;

    ptr->write("This is a test.", strlen("This is a test."));

    This of course does not work because templates don't have virtual
    functions and streams are templates. I was being stupid again.
    , Jan 30, 2006
    #2
    1. Advertising

  3. Rolf Magnus Guest

    wrote:

    > wrote:
    >> Using ostringstream the buffer gets increased to allow data to be
    >> appended when needed at least when you call <<. I was under the
    >> impression that write() also did but I am having problems that make me
    >> doubt that. Can I depend on the behavior of something like this?
    >>
    >> ostringstream os;
    >>
    >> os.write("This is a test.", strlen("This is a test."));
    >> cout << os.str() << endl;
    >>
    >> If so my problem is obviously caused by something else...

    >
    > I realized what the problem was. I was using iostream as a polymorphic
    > entity and it isn't.


    How did you get that idea? iostreams are polymorphic.

    > Code above would have looked more like this logically invalid code:
    >
    > ostringstream os;
    > ostream * ptr = &os;
    >
    > ptr->write("This is a test.", strlen("This is a test."));
    >
    > This of course does not work because templates don't have virtual
    > functions and streams are templates.


    Again, this is a false assumption. What makes you think that a class
    template cannot have virtual functions?
    Rolf Magnus, Jan 31, 2006
    #3
  4. Guest

    Rolf Magnus wrote:
    > wrote:
    >
    > > wrote:
    > >> Using ostringstream the buffer gets increased to allow data to be
    > >> appended when needed at least when you call <<. I was under the
    > >> impression that write() also did but I am having problems that make me
    > >> doubt that. Can I depend on the behavior of something like this?
    > >>
    > >> ostringstream os;
    > >>
    > >> os.write("This is a test.", strlen("This is a test."));
    > >> cout << os.str() << endl;
    > >>
    > >> If so my problem is obviously caused by something else...

    > >
    > > I realized what the problem was. I was using iostream as a polymorphic
    > > entity and it isn't.

    >
    > How did you get that idea? iostreams are polymorphic.


    In order for a class to be polymorphic it has to have virtual
    functions. The iostreams in the std lib do not. They are therefore
    not polymorphic.

    If you doubt this then just do what I did: Call write() on a
    stringstream from a pointer to type iostream and see what happens.
    >
    > > Code above would have looked more like this logically invalid code:
    > >
    > > ostringstream os;
    > > ostream * ptr = &os;
    > >
    > > ptr->write("This is a test.", strlen("This is a test."));
    > >
    > > This of course does not work because templates don't have virtual
    > > functions and streams are templates.

    >
    > Again, this is a false assumption. What makes you think that a class
    > template cannot have virtual functions?


    It was either in the book "Generic Programming" or "Template
    Metaprogramming" that I first read this; I believe in the former as it
    is part of the reasoning behind policies. Tests with my compiler
    generate errors. There is also a discussion on comp.lang.c++.moderated
    entitled "Why a template function cannot be a virtual function?". I
    would paste a link but copy paste has decided not to work and I will
    probably now have to reboot my computer. You should be able to find it
    yourself with the title.
    , Jan 31, 2006
    #4
  5. Pete C Guest

    > Code above would have looked more like this
    > logically invalid code:
    >
    > ostringstream os;
    > ostream * ptr = &os;
    >
    > ptr->write("This is a test.", strlen("This is a test."));
    >
    > This of course does not work because templates don't have virtual
    > functions and streams are templates. I was being stupid again.


    No, that code is absolutely fine. Your problem must lie somewhere else.
    Pete C, Jan 31, 2006
    #5
  6. In message <>,
    writes
    >
    >Rolf Magnus wrote:
    >> wrote:
    >>
    >> > wrote:
    >> >> Using ostringstream the buffer gets increased to allow data to be
    >> >> appended when needed at least when you call <<. I was under the
    >> >> impression that write() also did but I am having problems that make me
    >> >> doubt that. Can I depend on the behavior of something like this?
    >> >>
    >> >> ostringstream os;
    >> >>
    >> >> os.write("This is a test.", strlen("This is a test."));
    >> >> cout << os.str() << endl;
    >> >>
    >> >> If so my problem is obviously caused by something else...
    >> >
    >> > I realized what the problem was. I was using iostream as a polymorphic
    >> > entity and it isn't.

    >>
    >> How did you get that idea? iostreams are polymorphic.

    >
    >In order for a class to be polymorphic it has to have virtual
    >functions.


    In order for a class to be polymorphic all it needs is to have derived
    classes. It's only to make RTTI and dynamic_cast work that it has to
    have virtual functions.

    > The iostreams in the std lib do not. They are therefore
    >not polymorphic.
    >
    >If you doubt this then just do what I did: Call write() on a
    >stringstream from a pointer to type iostream and see what happens.
    >>


    #include <iostream>
    #include <ostream>
    #include <sstream>

    int main()
    {
    std::eek:stringstream s;
    std::eek:stream * p = &s;
    p->write("abcdefg", 7);
    std::cout << s.str() << '\n';
    }

    writes this for me:

    abcdefg

    I think your problem is elsewhere.

    --
    Richard Herring
    Richard Herring, Jan 31, 2006
    #6
  7. Guest

    Richard Herring wrote:
    > In message <>,
    > writes


    > >In order for a class to be polymorphic it has to have virtual
    > >functions.

    >
    > In order for a class to be polymorphic all it needs is to have derived
    > classes. It's only to make RTTI and dynamic_cast work that it has to
    > have virtual functions.


    If you say so. I'll believe the language standard and common use of
    the term though.

    > #include <iostream>
    > #include <ostream>
    > #include <sstream>
    >
    > int main()
    > {
    > std::eek:stringstream s;
    > std::eek:stream * p = &s;
    > p->write("abcdefg", 7);
    > std::cout << s.str() << '\n';
    > }
    >
    > writes this for me:
    >
    > abcdefg
    >
    > I think your problem is elsewhere.


    Yes it does. streambuf is polymorphic (its public interface calls
    protected virtual members). Removing the abstract reference fixed my
    problem and since streams are NOT polymorphic it tricked me. At this
    point it doesn't matter...some change I made along the line fixed it
    because the abstract reference now functions.
    , Jan 31, 2006
    #7
  8. Rolf Magnus Guest

    wrote:

    >> > wrote:
    >> >> Using ostringstream the buffer gets increased to allow data to be
    >> >> appended when needed at least when you call <<. I was under the
    >> >> impression that write() also did but I am having problems that make me
    >> >> doubt that. Can I depend on the behavior of something like this?
    >> >>
    >> >> ostringstream os;
    >> >>
    >> >> os.write("This is a test.", strlen("This is a test."));
    >> >> cout << os.str() << endl;
    >> >>
    >> >> If so my problem is obviously caused by something else...
    >> >
    >> > I realized what the problem was. I was using iostream as a polymorphic
    >> > entity and it isn't.

    >>
    >> How did you get that idea? iostreams are polymorphic.

    >
    > In order for a class to be polymorphic it has to have virtual
    > functions.


    Right.

    > The iostreams in the std lib do not.


    Again, this is _not_ true. They do have virtual member functions.

    > They are therefore not polymorphic.
    >
    > If you doubt this


    I don't just doubt it. I know it's wrong.

    > then just do what I did: Call write() on a stringstream from a pointer to
    > type iostream and see what happens.


    #include <iostream>

    int main()
    {
    std::stringstream stream;
    std::iostream* p = &stream;
    p->write("x\n", 2);
    std::cout << stream.str();
    }

    The output of the above program on my computer is:

    x

    That's exactly what I expect.

    > > Code above would have looked more like this logically invalid code:
    >> >
    >> > ostringstream os;
    >> > ostream * ptr = &os;
    >> >
    >> > ptr->write("This is a test.", strlen("This is a test."));
    >> >
    >> > This of course does not work because templates don't have virtual
    >> > functions and streams are templates.

    >>
    >> Again, this is a false assumption. What makes you think that a class
    >> template cannot have virtual functions?

    >
    > It was either in the book "Generic Programming" or "Template
    > Metaprogramming" that I first read this; I believe in the former as it
    > is part of the reasoning behind policies. Tests with my compiler
    > generate errors.


    How did you test? Try this:

    #include <iostream>

    template<typename T>
    class Base
    {
    public:
    virtual void test()
    {
    std::cout << "This is Base<>::test()\n";
    }
    };

    template<typename T>
    class Derived : public Base<T>
    {
    public:
    void test()
    {
    std::cout << "This is Derived<>::test()\n";
    }
    };

    int main()
    {
    Derived<char> d;
    Base<char>* p = &d;
    p->test();
    }

    > There is also a discussion on comp.lang.c++.moderated entitled "Why a
    > template function cannot be a virtual function?".


    A function template cannot be virtual, but a normal member function of a
    class template can.
    Rolf Magnus, Jan 31, 2006
    #8
  9. Rolf Magnus Guest

    wrote:

    >> > wrote:
    >> >> Using ostringstream the buffer gets increased to allow data to be
    >> >> appended when needed at least when you call <<. I was under the
    >> >> impression that write() also did but I am having problems that make me
    >> >> doubt that. Can I depend on the behavior of something like this?
    >> >>
    >> >> ostringstream os;
    >> >>
    >> >> os.write("This is a test.", strlen("This is a test."));
    >> >> cout << os.str() << endl;
    >> >>
    >> >> If so my problem is obviously caused by something else...
    >> >
    >> > I realized what the problem was. I was using iostream as a polymorphic
    >> > entity and it isn't.

    >>
    >> How did you get that idea? iostreams are polymorphic.

    >
    > In order for a class to be polymorphic it has to have virtual
    > functions.


    Right.

    > The iostreams in the std lib do not.


    Ok, maybe only the streambufs, not the streams themselves. Not sure about
    this.

    > They are therefore not polymorphic.
    >
    > If you doubt this then just do what I did: Call write() on a stringstream
    > from a pointer to type iostream and see what happens.


    #include <iostream>

    int main()
    {
    std::stringstream stream;
    std::iostream* p = &stream;
    p->write("x\n", 2);
    std::cout << stream.str();
    }

    The output of the above program on my computer is:

    x

    That's exactly what I expect.

    > > Code above would have looked more like this logically invalid code:
    >> >
    >> > ostringstream os;
    >> > ostream * ptr = &os;
    >> >
    >> > ptr->write("This is a test.", strlen("This is a test."));
    >> >
    >> > This of course does not work because templates don't have virtual
    >> > functions and streams are templates.

    >>
    >> Again, this is a false assumption. What makes you think that a class
    >> template cannot have virtual functions?

    >
    > It was either in the book "Generic Programming" or "Template
    > Metaprogramming" that I first read this; I believe in the former as it
    > is part of the reasoning behind policies. Tests with my compiler
    > generate errors.


    How did you test? Try this:

    #include <iostream>

    template<typename T>
    class Base
    {
    public:
    virtual void test()
    {
    std::cout << "This is Base<>::test()\n";
    }
    };

    template<typename T>
    class Derived : public Base<T>
    {
    public:
    void test()
    {
    std::cout << "This is Derived<>::test()\n";
    }
    };

    int main()
    {
    Derived<char> d;
    Base<char>* p = &d;
    p->test();
    }

    > There is also a discussion on comp.lang.c++.moderated entitled "Why a
    > template function cannot be a virtual function?".


    A function template cannot be virtual, but a normal member function of a
    class template can.
    Rolf Magnus, Jan 31, 2006
    #9
  10. In message <>,
    writes
    >
    >Richard Herring wrote:
    >> In message <>,
    >> writes

    >
    >> >In order for a class to be polymorphic it has to have virtual
    >> >functions.

    >>
    >> In order for a class to be polymorphic all it needs is to have derived
    >> classes. It's only to make RTTI and dynamic_cast work that it has to
    >> have virtual functions.

    >
    >If you say so. I'll believe the language standard and common use of
    >the term though.


    OK, I'll rephrase that. You are correct about the definition of
    polymorphism, but the whole issue of polymorphism is a red herring and
    what you were really talking about, access to a base class using a
    pointer to a derived class, is not polymorphism, and doesn't need
    virtual functions to exist:

    4.10/3 An rvalue of type "pointer to cv D", where D is a class type,
    can be converted to type "pointer to cv B", where B is a base class of
    D. [...] The result of the conversion is a pointer to the base class
    sub-object of the derived class object.

    >> #include <iostream>
    >> #include <ostream>
    >> #include <sstream>
    >>
    >> int main()
    >> {
    >> std::eek:stringstream s;
    >> std::eek:stream * p = &s;
    >> p->write("abcdefg", 7);
    >> std::cout << s.str() << '\n';
    >> }
    >>
    >> writes this for me:
    >>
    >> abcdefg
    >>
    >> I think your problem is elsewhere.

    >
    >Yes it does. streambuf is polymorphic (its public interface calls
    >protected virtual members). Removing the abstract reference fixed my
    >problem and since streams are NOT polymorphic it tricked me. At this
    >point it doesn't matter...some change I made along the line fixed it
    >because the abstract reference now functions.
    >


    --
    Richard Herring
    Richard Herring, Feb 1, 2006
    #10
  11. Guest

    Richard Herring wrote:
    > In message <>,
    > writes
    > >
    > >Richard Herring wrote:


    > >> In order for a class to be polymorphic all it needs is to have derived
    > >> classes. It's only to make RTTI and dynamic_cast work that it has to
    > >> have virtual functions.

    > >
    > >If you say so. I'll believe the language standard and common use of
    > >the term though.

    >
    > OK, I'll rephrase that. You are correct about the definition of
    > polymorphism, but the whole issue of polymorphism is a red herring and
    > what you were really talking about, access to a base class using a
    > pointer to a derived class, is not polymorphism, and doesn't need
    > virtual functions to exist:


    No, it is not polymorphism. Calls made to overriden members of
    non-virtual functions result in the call being made to the parent type.
    If the overridden members need to do such things as bounds checking on
    an internal buffer before doing the stuff normally performed by the
    function ... and that stuff is not done because the function called was
    the one belonging to the parent ... then you have problems.

    Such a design obviously has problems, which is why streams work off of
    buffers that ARE polymorphic.
    , Feb 1, 2006
    #11
    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. Voronkov Konstantin
    Replies:
    1
    Views:
    714
    Voronkov Konstantin
    Nov 18, 2005
  2. Alex Vinokur

    ostringstream and memcpy

    Alex Vinokur, Jan 18, 2006, in forum: C++
    Replies:
    3
    Views:
    508
    Ian Collins
    Jan 19, 2006
  3. Olaf van der Spek

    std::ostringstream and \r\n

    Olaf van der Spek, May 3, 2006, in forum: C++
    Replies:
    4
    Views:
    507
    Old Wolf
    May 5, 2006
  4. Angus
    Replies:
    4
    Views:
    729
    Gregg N
    Jan 14, 2007
  5. Replies:
    3
    Views:
    359
Loading...

Share This Page