Connecting Tech Pros Worldwide Forums | Help | Site Map

map of ostringstreams behaves unexpectedly

eric
Guest
 
Posts: n/a
#1: Jul 23 '05
hello

i compile the following code in MSVC++6:

map < string, ostringstream > smap;
smap["key1"] << "val1";
smap["key2"] << "val2";

map < string, ostringstream >::const_iterator i;
for (i = smap.begin();
i!= smap.end(); i++)
cout << i->first << "|" << i->second.str() << endl;

i expect it to output:

key1|val1
key2|val2

in fact the output is:

key1|
key2|

what am i doing wrong?

thanks
eric

wittempj@hotmail.com
Guest
 
Posts: n/a
#2: Jul 23 '05

re: map of ostringstreams behaves unexpectedly


A map is meant to assosciate two pieces of data, like below. What youre
doing with the second element looks weird to me, as a string stream
itself is no class representing data by itself

#include <iostream>
#include <map>
#include <string>
#include <sstream>

using namespace std;

int main()
{

map < string, string > smap;
stringstream s;

s << "val1";
smap["key1"] = s.str();
s.str("");
s << "val2";
smap["key2"] = s.str();

map < string, string >::const_iterator i;
for (i = smap.begin(); i!= smap.end(); ++i)
cout << (*i).first << "|" << i->second << endl;

}

Ron Natalie
Guest
 
Posts: n/a
#3: Jul 23 '05

re: map of ostringstreams behaves unexpectedly


wittempj@hotmail.com wrote:[color=blue]
> A map is meant to assosciate two pieces of data, like below. What youre
> doing with the second element looks weird to me, as a string stream
> itself is no class representing data by itself[/color]

A stringstream is as much data as anything else. In it's heart it's
got a buffer full of the outputed characters. << is as a valid
way of manipulating data as other methods.

Ron Natalie
Guest
 
Posts: n/a
#4: Jul 23 '05

re: map of ostringstreams behaves unexpectedly


eric wrote:[color=blue]
> hello
>
> i compile the following code in MSVC++6:
>
> map < string, ostringstream > smap;
> smap["key1"] << "val1";
> smap["key2"] << "val2";
>
> map < string, ostringstream >::const_iterator i;
> for (i = smap.begin();
> i!= smap.end(); i++)[/color]

You might try flushing the buffer, but it's not supposed to be necessary.
i->second.flush();[color=blue]
> cout << i->first << "|" << i->second.str() << endl;
>[/color]
Howard Hinnant
Guest
 
Posts: n/a
#5: Jul 23 '05

re: map of ostringstreams behaves unexpectedly


In article <420e3657$0$11722$9a6e19ea@news.newshosting.com> ,
Ron Natalie <ron@sensor.com> wrote:
[color=blue]
> wittempj@hotmail.com wrote:[color=green]
> > A map is meant to assosciate two pieces of data, like below. What youre
> > doing with the second element looks weird to me, as a string stream
> > itself is no class representing data by itself[/color]
>
> A stringstream is as much data as anything else. In it's heart it's
> got a buffer full of the outputed characters. << is as a valid
> way of manipulating data as other methods.[/color]

A container's value_type must be copyconstructible and assignable.
stringstreams are neither. I'm surprised the example even compiled for
the OP (it doesn't for me).

That being said, if we get move semantics in C++0X (
http://www.open-std.org/jtc1/sc22/wg...004/n1690.html ), I
expect the OP's code to compile and work as expected.

-Howard
Ron Natalie
Guest
 
Posts: n/a
#6: Jul 23 '05

re: map of ostringstreams behaves unexpectedly


Howard Hinnant wrote:
[color=blue]
> A container's value_type must be copyconstructible and assignable.
> stringstreams are neither. I'm surprised the example even compiled for
> the OP (it doesn't for me).
>[/color]
There you have a point.
wittempj@hotmail.com
Guest
 
Posts: n/a
#7: Jul 23 '05

re: map of ostringstreams behaves unexpectedly


I couldn't compile it either (on gcc 3.4.2), that's what triggered my
slightly unscientific comments ....

Ron Natalie
Guest
 
Posts: n/a
#8: Jul 23 '05

re: map of ostringstreams behaves unexpectedly


wittempj@hotmail.com wrote:[color=blue]
> I couldn't compile it either (on gcc 3.4.2), that's what triggered my
> slightly unscientific comments ....
>[/color]
It compiles because he didn't do anything that in his implementation
tripped across the lack of an accessible copy constructor/assignment
op. To stick non-copyable objects in a container is undefined behavior.
No requirement for the compiler to notice the error (and very difficult
to do in some cases).
Pete Becker
Guest
 
Posts: n/a
#9: Jul 23 '05

re: map of ostringstreams behaves unexpectedly


Ron Natalie wrote:[color=blue]
> wittempj@hotmail.com wrote:
>[color=green]
>> I couldn't compile it either (on gcc 3.4.2), that's what triggered my
>> slightly unscientific comments ....
>>[/color]
> It compiles because he didn't do anything that in his implementation
> tripped across the lack of an accessible copy constructor/assignment
> op.[/color]

Not being copy constructible etc. doesn't mean not having an accessible
copy constructor/assignment op. It means that the semantics of
copyability as defined for containers aren't met. This subtle-sounding
distinction is important because it means that it's okay for the
implementation to provide a copy constructor and an assignment operator,
but they don't have to do what a container expects. In particular,
copying these things can be used to initialize global stream objects
(such as cout), which doesn't involve copying buffer contents. That's
the old ostream_with_assign stuff; it's still legitimate, and some
implementations use it. Which is why the original code compiled, but
didn't do what its author expected.

--

Pete Becker
Dinkumware, Ltd. (http://www.dinkumware.com)
Closed Thread