Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > ostringstream and write()

Reply
Thread Tools

ostringstream and write()

 
 
roberts.noah@gmail.com
Guest
Posts: n/a
 
      01-30-2006
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...

 
Reply With Quote
 
 
 
 
roberts.noah@gmail.com
Guest
Posts: n/a
 
      01-30-2006

http://www.velocityreviews.com/forums/(E-Mail Removed) 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.

 
Reply With Quote
 
 
 
 
Rolf Magnus
Guest
Posts: n/a
 
      01-31-2006
(E-Mail Removed) wrote:

> (E-Mail Removed) 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?

 
Reply With Quote
 
roberts.noah@gmail.com
Guest
Posts: n/a
 
      01-31-2006

Rolf Magnus wrote:
> (E-Mail Removed) wrote:
>
> > (E-Mail Removed) 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.

 
Reply With Quote
 
Pete C
Guest
Posts: n/a
 
      01-31-2006
> 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.

 
Reply With Quote
 
Richard Herring
Guest
Posts: n/a
 
      01-31-2006
In message <(E-Mail Removed) om>,
(E-Mail Removed) writes
>
>Rolf Magnus wrote:
>> (E-Mail Removed) wrote:
>>
>> > (E-Mail Removed) 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:stringstream s;
std: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
 
Reply With Quote
 
roberts.noah@gmail.com
Guest
Posts: n/a
 
      01-31-2006

Richard Herring wrote:
> In message <(E-Mail Removed) om>,
> (E-Mail Removed) 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:stringstream s;
> std: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.

 
Reply With Quote
 
Rolf Magnus
Guest
Posts: n/a
 
      01-31-2006
(E-Mail Removed) wrote:

>> > (E-Mail Removed) 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.

 
Reply With Quote
 
Rolf Magnus
Guest
Posts: n/a
 
      01-31-2006
(E-Mail Removed) wrote:

>> > (E-Mail Removed) 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.

 
Reply With Quote
 
Richard Herring
Guest
Posts: n/a
 
      02-01-2006
In message <(E-Mail Removed) .com>,
(E-Mail Removed) writes
>
>Richard Herring wrote:
>> In message <(E-Mail Removed) om>,
>> (E-Mail Removed) 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:stringstream s;
>> std: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
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
How do you create and use an ostringstream in an initialisation list? Adam Nielsen C++ 8 10-17-2007 07:09 AM
ostringstream and sgetn() weirdness whatdoineed2do@yahoo.co.uk C++ 3 07-03-2007 04:01 PM
std::ostringstream and \r\n Olaf van der Spek C++ 4 05-04-2006 11:42 PM
ostringstream and memcpy Alex Vinokur C++ 3 01-19-2006 07:15 AM
Why std::ostringstream inserts number group delimeter and how to disable this mode? Voronkov Konstantin C++ 1 11-18-2005 10:20 AM



Advertisments