map of ostringstreams behaves unexpectedly

E

eric

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
 
W

wittempj

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;

}
 
R

Ron Natalie

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

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.
 
R

Ron Natalie

eric said:
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++)

You might try flushing the buffer, but it's not supposed to be necessary.
i->second.flush();
 
H

Howard Hinnant

Ron Natalie said:
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.

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/wg21/docs/papers/2004/n1690.html ), I
expect the OP's code to compile and work as expected.

-Howard
 
R

Ron Natalie

Howard said:
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).
There you have a point.
 
W

wittempj

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

Ron Natalie

I couldn't compile it either (on gcc 3.4.2), that's what triggered my
slightly unscientific comments ....
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).
 
P

Pete Becker

Ron said:
It compiles because he didn't do anything that in his implementation
tripped across the lack of an accessible copy constructor/assignment
op.

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.
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,201
Messages
2,571,049
Members
47,653
Latest member
YvonneJif

Latest Threads

Top