Hey everyone, what am I missing here?
Background: Essentially, I've got an array of C structures with string
names and values, but the array contains multiple entries of the same
name for several values, and I'm trying to convert this to a string
format where each entry is a unique name followed by a comma-separated
value list. I need to take two passes over the input list. The first
one gathers multiple values into a single list for each unique name,
the second pass builds the output string from the resulting map data.
I'm using a map of strings to ostringstreams, and I'm trying to use
map::insert to either insert a new pair, or locate the previously
inserted pair by name. In either case, I simply append the next value
on to the value string. I thought to build the map from a string name
and an ostringstream value because the value data has to be converted
from binary to string format, so I could just continue to append
values until I was done. For the second traversal, I use a vector of
map::iterators that I built during the first traversal in order to
maintain the original data order.
-------------
using namespace std;
string MakeNVString(NameValue * namevals, unsigned nvcnt)
{
// build a map of names to comma-separated value string-streams
// and a vector of iterators into the map ordered by input traversal
map<string, ostringstream> avsmap;
vector<map<string, ostringstream>::iterator> order;
for (unsigned i = 0; i < nvcnt; i++)
{
// locate name by inserting the name and a new stream value
pair<map<string, ostringstream>::iterator, bool> pr =
avsmap.insert(map<string, ostringstream>::value_type(
string((char*)namevals[i].name),
ostringstream()));
// if insert succeeded, save iterator in traversal order vector
// else it already exists, so prepend a comma before next value
ostringstream & vs = pr.first->second;
if (pr.second)
order.push_back(pr.first);
else
vs << ',';
// add the value string to the value stream
switch(namevals[i].valueType)
{
case NS_VALUE_TYPE_STRINGZ:
vs << (char*)namevals[i].value;
break;
// more cases ...
}
}
// build the return string from the intermediate map
ostringstream os;
for (vector<map<string, ostringstream>::iterator>::iterator
vp = order.begin(); vp != order.end(); ++vp)
{
map<string, ostringstream>::iterator ip = *vp;
os << '(' << ip->first << '=' << ip->second.str() << ')';
}
return os.str();
}
-------------
Problem: The trouble is that my ostringstream objects don't get any
data inserted. I get the names back properly from the first map value
component (the string), but the ostringstream is (apparently) empty.
I'm probably doing something stupid like writing to a temporary object
somewhere instead of the ostringstream in my map-building loop, but I
can't see it.
Any ideas?
Thanks in advance,
John
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
0
|
|
|
|
Reply
|
jcalcote
|
11/18/2003 11:53:55 AM |
|
John Calcote wrote:
> string MakeNVString(NameValue * namevals, unsigned nvcnt)
> {
> // build a map of names to comma-separated value string-streams
> // and a vector of iterators into the map ordered by input traversal
> map<string, ostringstream> avsmap;
This is undefined behaviour. 23.1/3 says that objects
stored in Standard Library containers must be
CopyConstructible. The ostringstream type cannot be copied
as it derives from basic_ios<char> which has a private copy
constructor and assignment operator.
As an alternative, how about using a
boost::shared_ptr< std::ostringstream >
in the map?
> pair<map<string, ostringstream>::iterator, bool> pr =
> avsmap.insert(map<string, ostringstream>::value_type(
> string((char*)namevals[i].name),
> ostringstream()));
I'm surprised this compiles. The value_type of a std::map
is a std::pair, and constructing a std::pair from two
objects will copy each of the objects. As ostringstream has
an inaccessible copy constructor, I don't see how this can
compile.
> I'm probably doing something stupid like writing to a temporary object
> somewhere instead of the ostringstream in my map-building loop, but I
> can't see it.
I can easily believe this. You apparently have a non-
conformant Standard Library implementation that allows
ostringstreams to be copied. If instead of raw
ostringstreams, you hold them by shared pointer, it won't
matter whether or not you are writing to a temporary object.
--
Richard Smith
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
0
|
|
|
|
Reply
|
Richard
|
11/18/2003 8:00:16 PM
|
|
On 18 Nov 2003 06:53:55 -0500, jcalcote@novell.com (John Calcote)
wrote:
> map<string, ostringstream> avsmap;
That's illegal. ostringstream doesn't satisfy the container element
requirements since it isn't copyable. You need something like:
map<string, ostringstream*> avsmap;
or
map<string, shared_ptr<ostringstream> > avsmap;
Tom
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
0
|
|
|
|
Reply
|
tom_usenet
|
11/18/2003 8:07:39 PM
|
|
Thanks so much for the reply.
> This is undefined behaviour. 23.1/3 says that objects
> stored in Standard Library containers must be
> CopyConstructible. The ostringstream type cannot be copied
> as it derives from basic_ios<char> which has a private copy
> constructor and assignment operator.
I figured this out after switching from VC6 to VC7, which apparently
does a better job of only allowing that which is legal (not perfect,
but much better). Also the error messages are a bit more intelligible.
> As an alternative, how about using a
>
> boost::shared_ptr< std::ostringstream >
I actually reverted to string and got it working without too much
fuss, but I really like the idea of shared_ptr(ostringstream). That's
a neat idea - I may go back to that method just for fun. The problem
with my string implementation is that concatenation of strings is not
nearly as efficient as ostringstream insertion.
Thanks again,
John
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
0
|
|
|
|
Reply
|
jcalcote
|
11/19/2003 6:40:05 PM
|
|
|
3 Replies
406 Views
(page loaded in 0.061 seconds)
Similiar Articles: map of string to ostringstream - comp.lang.c++.moderated ...Hey everyone, what am I missing here? Background: Essentially, I've got an array of C structures with string names and values, but the array contains... shared_ptr as map key - comp.lang.c++.moderatedmap of string to ostringstream - comp.lang.c++.moderated ... You need something like: map<string, ostringstream*> avsmap; or map<string, shared_ptr ... inserting class objects into maps - comp.lang.c++.moderated ...map of string to ostringstream - comp.lang.c++.moderated ... The first one gathers multiple values into a ... to ostringstreams, and I'm trying to use map::insert to ... modify map values through an iterator - comp.lang.c++.moderated ...map of string to ostringstream - comp.lang.c++.moderated ... modify map values through an ... to modify the values of a map through an iterator? As I ... map of string to ... How can i get the first letter of this string - comp.lang.ruby ...map of string to ostringstream - comp.lang.c++.moderated ... I get the names back properly from the first map value component (the string), but the ostringstream is ... Cannot align new vector object - comp.graphics.apps.paint-shop-pro ...map of string to ostringstream - comp.lang.c++.moderated ... For the second traversal, I use a vector of map ... Problem: The trouble is that my ostringstream objects don ... Unexpected exception - comp.dcom.sys.ciscomap of string to ostringstream - comp.lang.c++.moderated ... Clear a stringstream - Velocity Reviews - Computer Hardware This is a subtle variation of a question I posted ... parsing name value pairs - comp.lang.awkmap of string to ostringstream - comp.lang.c++.moderated ... parsing name value pairs - comp.lang.awk map of string to ostringstream - comp.lang.c++.moderated ... parsing ... map of string to ostringstream - comp.lang.c++.moderated ...Hey everyone, what am I missing here? Background: Essentially, I've got an array of C structures with string names and values, but the array contains... ostringstream - C++ Reference - cplusplus.com - The C++ Resources ...ostringstream provides an interface to manipulate strings as if they were output streams. The objects of this class maintain internally a pointer to a stringbuf ... 7/19/2012 7:10:37 PM
|