C++Talk.NET Forum Index C++Talk.NET
C++ language newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

How to copy maps to ostream_iterators?

 
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ Language (Moderated)
View previous topic :: View next topic  
Author Message
Siegfried Heintze
Guest





PostPosted: Tue May 02, 2006 11:06 am    Post subject: How to copy maps to ostream_iterators? Reply with quote



I have the following code that I am trying to compile with g++ 3.2 (see
below).

The syntax error messages are telling me there is no function operator<<
defined to accept a std::pair. This is not true: as you can see I have
defined such a function. I've seen this work with other compilers. I've
tried

std::ostream& operator<<(std::ostream&os, const
std::pair<std::string,std::string>&x){ .... }

but that does not work either.

Can anyone tell me what I am doing wrong?
Thanks,
Siegfried


template <typename K, typename V>
inline std::ostream& operator<<(std::ostream& os, const std::pair<K,V>& x)
{
return os << "[" << x.first << ","<< x.second << "]";
}

std::map<std::string,std::string> m;
std::string hello="hello", world="world";
m[hello]=world;

std::copy(m.begin(),m.end(),
std::ostream_iterator<std::pair<std::string,std::string> >(std::cout));




[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Back to top
Thomas Maeder
Guest





PostPosted: Tue May 02, 2006 9:06 pm    Post subject: Re: How to copy maps to ostream_iterators? Reply with quote



"Siegfried Heintze" <siegfried (AT) heintze (DOT) com> writes:



Quote:
I have the following code that I am trying to compile with g++ 3.2

(see below).



The syntax error messages are telling me there is no function

operator<< defined to accept a std::pair.



Syntax errors? I'd expect to see something like "no match". The syntax

seems ok, though.





Quote:
This is not true: as you can see I have defined such a function.



But not in the right namespace. Argument dependent lookup causes it to

be looked up in namespace std; and only there, because some overloads

of operator<< are found there.





Quote:
I've seen this work with other compilers. I've tried



std::ostream& operator<<(std::ostream&os, const

std::pair<std::string,std::string>&x){ .... }



but that does not work either.



Can anyone tell me what I am doing wrong?

Thanks,

Siegfried





template <typename K, typename V

inline std::ostream& operator<<(std::ostream& os, const std::pair<K,V>& x)

{

return os << "[" << x.first << ","<< x.second << "]";

}



std::map<std::string,std::string> m;

std::string hello="hello", world="world";

m[hello]=world;



std::copy(m.begin(),m.end(),

std::ostream_iterator<std::pair<std::string,std::string> >(std::cout));



The value_type of this map type is

std::pair<std::string const, std::string>, which is different from the

type you use.





The following program compiles:



#include <map>

#include <algorithm>

#include <iostream>

#include <ostream>

#include <iterator>



namespace std

{

template <typename K, typename V>

inline std::ostream& operator<<(std::ostream& os, std::pair<K,V> const & x)

{

return os << "[" << x.first << "," << x.second << "]";

}

}



int main()

{

typedef std::map<std::string,std::string> map_type;

map_type m;



std::string hello("hello");

std::string world("world");

m[hello] = world;



std::copy(m.begin(),m.end(),

std::ostream_iterator<map_type::value_type>(std::cout));

}



The problem is that strictly speaking, it has undefined behavior,

because we mere users are not allowed to do anything in namespace std

other than provide specializations of Standard templates for our own

types.





What about



#include <map>

#include <algorithm>

#include <iostream>

#include <ostream>

#include <iterator>



template <typename pair_type>

struct pair_printer

{

void operator()(pair_type const & x)

{

std::cout << "[" << x.first << ","<< x.second << "]";

}

};



int main()

{

typedef std::map<std::string,std::string> map_type;

map_type m;



std::string hello("hello");

std::string world("world");

m[hello] = world;



std::for_each(m.begin(),m.end(),

pair_printer<map_type::value_type>());

}



?



[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Back to top
Carl Barron
Guest





PostPosted: Wed May 03, 2006 10:06 am    Post subject: Re: How to copy maps to ostream_iterators? Reply with quote



In article <4456d1ff@mamba.>, Siegfried Heintze <siegfried (AT) heintze (DOT) com>
wrote:

Quote:
The syntax error messages are telling me there is no function operator
defined to accept a std::pair. This is not true:

Its true since operator << ()'s args are in namespace std and operator
<< is called from namespace std [in std::ostream_iterator<...>()
lookup only occurs in namespace std.

Quote:
as you can see I have
defined such a function. I've seen this work with other compilers. I've
tried

std::ostream& operator<<(std::ostream&os, const
std::pair<std::string,std::string>&x){ .... }

but that does not work either.
1) use for_each

class print_one
{
std::ostream &os;
public:
print_one(std::ostream &a)Surpriseds(a){}
void operator () (const std::pair<const
std::string,std::string> &p)
{
// print as ostream_iterator would have
}
};

for_eacn(m.begin(),m.end(),print_one(std::cout));

2) write an output iterator to handle std::pair outside of namespace
std.

3) STRICTLY ILLEGAL in terms of the standard. put your operator << ()
in namespace std.

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Back to top
kanze
Guest





PostPosted: Thu May 04, 2006 9:22 pm    Post subject: Re: How to copy maps to ostream_iterators? Reply with quote

Carl Barron wrote:
Quote:
In article <4456d1ff@mamba.>, Siegfried Heintze
siegfried (AT) heintze (DOT) com> wrote:

The syntax error messages are telling me there is no
function operator<< defined to accept a std::pair. This is
not true:

Its true since operator << ()'s args are in namespace std and
operator << is called from namespace std [in
std::ostream_iterator<...>() lookup only occurs in namespace
std.

as you can see I have defined such a function. I've seen
this work with other compilers. I've tried

std::ostream& operator<<(std::ostream&os, const
std::pair<std::string,std::string>&x){ .... }
but that does not work either.

It might be worth pointing out that the reason it works with
older compilers is that they don't use two phase lookup. It
will still work with modern compilers outside of a template. It
is only when instantiating a template that lookup is restricted
to ADL. And then only for dependant names, and for the lookup
which takes place in the instantiation context.

[...]
Quote:
3) STRICTLY ILLEGAL in terms of the standard. put your
operator << () in namespace std.

Illegal, but it will work everywhere.

More importantly, of course, overloading an operator<< for any
standard class is something that you would never want to do
outside of small experimental programs. Why should your
component get the priviledge, and no other?

My usual solution for this sort of thing is a class which
implicitly converts to or from the standard type. In this case,
something along the lines of:

class MyPair
{
public:
MyPair( map_type::value_type const& v ) : myValue( v ) {}
friend std::ostream& operator<<( std::ostream& dest,
MyPair const& obj ) ;
private:
map_type::value_type myValue ;
} ;

Something along the lines of:

std::copy( m.begin(), m.end(),
std::ostream_iterator< MyPair >( std::cout ) ) ;

Should then do the job.

--
James Kanze GABI Software
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Back to top
Display posts from previous:   
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ Language (Moderated) All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.