By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
446,227 Members | 1,240 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 446,227 IT Pros & Developers. It's quick & easy.

map of ostringstreams behaves unexpectedly

P: n/a
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
Jul 23 '05 #1
Share this Question
Share on Google+
8 Replies


P: n/a
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;

}

Jul 23 '05 #2

P: n/a
wi******@hotmail.com wrote:
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.

Jul 23 '05 #3

P: n/a
eric wrote:
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(); cout << i->first << "|" << i->second.str() << endl;

Jul 23 '05 #4

P: n/a
In article <42***********************@news.newshosting.com> ,
Ron Natalie <ro*@sensor.com> wrote:
wi******@hotmail.com wrote:
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.


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
Jul 23 '05 #5

P: n/a
Howard Hinnant wrote:
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.
Jul 23 '05 #6

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

Jul 23 '05 #7

P: n/a
wi******@hotmail.com wrote:
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).
Jul 23 '05 #8

P: n/a
Ron Natalie wrote:
wi******@hotmail.com wrote:
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.


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)
Jul 23 '05 #9

This discussion thread is closed

Replies have been disabled for this discussion.