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 

Print map values with class as map member

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






PostPosted: Sun Aug 27, 2006 5:33 pm    Post subject: Print map values with class as map member Reply with quote



Hi,
I am new at C++ and have been trying to understand maps by developing a
small program but I cannot determine how to print out the values stored
in the maps. Once I understand how maps work, I'll move on to hashing
tables, just so that I get the understanding of their operation.

I'm having an issue and I think what I am attempting to perform is not
capable. I am attempting to create a class and then use that same
class as member of a map. The standard doesn't seem to not allow what
I'm attempting to perform but it doesn't work somehow:

#include <iostream>
using std::cout;
using std::endl;
using std::ostream;

#include<map>
using std::map;

#include <string>
using std::string;

#include <vector>
using std::vector;

/* Class M to be used as part of map. */

class M {
public:
M() {};
M(int, vector<int>) {int i = 0; vector <int> table2;};
~M() {};
private:
int i;
vector<int> mv;
};

ostream& operator<<(ostream &output, const int &x, const map<int, M>
&y) {
output << x << endl << y;
return output;
};

/* This will not work, a failed attempt.
ostream& operator<<(ostream &output, const &vector<int> mv ) {
output << x;
return output;
};
*/

int main()
{
vector<int> table1;
M t(20, table1); // generic values

// this was from an earlier programme to just get maps to work
okay.
table1.push_back(1);
table1.push_back(2);
table1.push_back(3);

map<int, M> map_test;

map_test[20] = t;

typedef map<int, M>::const_iterator con_it;

for( con_it x = map_test.begin(); x !=map_test.end(); ++x ) {
cout << x->first << endl << x->second << endl;
}
}

If I leave out this section:

typedef map<int, M>::const_iterator con_it;

for( con_it x = map_test.begin(); x !=map_test.end(); ++x ) {
cout << x->first << endl << x->second << endl;

The programme compiles and builds correctly. Once I add it in (without
the overloaded << operator), I have linker errors indicating that the
compiler cannot find an << operator that takes an int and a const "M."

As a work around, I've attempted to create an overloaded << operator to
accomodate my user defined map, but nothing seems to work correctly.
I've tried several things including:

1. Created two separate overloaded operators, one for the two parts of
the map: an int and a vector.
2. Created an overloaded << operator with the following parameters:
ostream, int, ostream and vector. (as const and non-const references)
3. Created an overloaded << operator with the following parameters:
ostream, map.

Am I attempting something not capable of working, that is using a class
as a member of a map? If I remove the class and just build a simple
map with two ints as members, I have no trouble. I've spent several
days on this but am not making much progress and would like to move on
to hash tables and learn those.

Could someone please suggest some feedback?

Kimi


[ 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: Mon Aug 28, 2006 8:26 am    Post subject: Re: Print map values with class as map member Reply with quote



In article <1156643171.935106.29900 (AT) h48g2000cwc (DOT) googlegroups.com>,
<testcpp (AT) gmail (DOT) com> wrote:

Quote:
Hi,
I am new at C++ and have been trying to understand maps by developing a
small program but I cannot determine how to print out the values stored
in the maps. Once I understand how maps work, I'll move on to hashing
tables, just so that I get the understanding of their operation.

I'm having an issue and I think what I am attempting to perform is not
capable. I am attempting to create a class and then use that same
class as member of a map. The standard doesn't seem to not allow what
I'm attempting to perform but it doesn't work somehow:
[snip]
class M {
public:
M() {};
M(int, vector<int>) {int i = 0; vector <int> table2;};
~M() {};
private:
int i;
vector<int> mv;
};

ostream& operator<<(ostream &output, const int &x, const map<int, M
&y) {
output << x << endl << y;
return output;
};
This has an invalid signature operator << takes two args not three.

you can accomplish this with explicitly << x and << y if you write a
proper operator << (std::ostream &,std::map<...> const &) except map
and ostream are in namespace std and your operator << is not so it
won't be found.
solution [fairly safe ] is a struct
struct my_map:std::map<int,M>{};
should get around this if you only default construct the map.

std::ostream & operator << (std::ostream &os,my_map const &m)
{
for(my_map::const_iterator it=m.begin();it!=m.end();++i)
os << it->first << ' ' << it->second << '\n';
return os;
}

Quote:
/* This will not work, a failed attempt.
ostream& operator<<(ostream &output, const &vector<int> mv ) {
output << x;
return output;
};
*/
std::ostream & operator << (std::ostream &os, const std::vector<int

&mv)
{
std::copy(m.begin(),m.end(),std::ostream_iterator<int>(os,"\n"));
return os;
}
[snip]

[ 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: Mon Aug 28, 2006 6:00 pm    Post subject: Re: Print map values with class as map member Reply with quote



Carl Barron wrote:
Quote:
In article <1156643171.935106.29900 (AT) h48g2000cwc (DOT) googlegroups.com>,
testcpp (AT) gmail (DOT) com> wrote:

I am new at C++ and have been trying to understand maps by
developing a small program but I cannot determine how to
print out the values stored in the maps. Once I understand
how maps work, I'll move on to hashing tables, just so that
I get the understanding of their operation.

I'm having an issue and I think what I am attempting to
perform is not capable. I am attempting to create a class
and then use that same class as member of a map. The
standard doesn't seem to not allow what I'm attempting to
perform but it doesn't work somehow:
[snip]
class M {
public:
M() {};
M(int, vector<int>) {int i = 0; vector <int> table2;};
~M() {};
private:
int i;
vector<int> mv;
};

ostream& operator<<(ostream &output, const int &x, const map<int, M
&y) {
output << x << endl << y;
return output;
};

This has an invalid signature operator << takes two args not three.

Even if it didn't, there is no << for a map (his third
parameter).

Quote:
you can accomplish this with explicitly << x and << y if you write a
proper operator << (std::ostream &,std::map<...> const &) except map
and ostream are in namespace std and your operator << is not so it
won't be found.

Except that he will be using std::map<int,M>, so functions
and/or operators in the same namespace as M should be found.
After that, it's a question of overload resolution. Something
like the following should work:

std::ostream&
operator<<( std::ostream& dest, std::map< int, M > const& obj )
{
for ( std::map< int, M >::const_iterator iter = obj.begin() ;
iter != obj.end() ;
++ iter ) {
dest << iter->first << ':' << iter->second << '\n' ;
}
return dest ;
}

Of course, that's only true if one of the arguments to the
std::map template is a user defined type. The above won't work
for std::map< int, std::string >, nor for std::map< int,
std::vector< int > >.

Quote:
/* This will not work, a failed attempt.
ostream& operator<<(ostream &output, const &vector<int> mv ) {
output << x;
return output;
};
*/
std::ostream & operator << (std::ostream &os, const std::vector<int
&mv)
{
std::copy(m.begin(),m.end(),std::ostream_iterator<int>(os,"\n"));
return os;
}
[snip]

Except that ADL will NOT find this operator<<. He'd need to put
it in namespace std, which is illegal.

--
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
alex
Guest





PostPosted: Thu Sep 07, 2006 11:28 pm    Post subject: Re: Print map values with class as map member Reply with quote

testcpp (AT) gmail (DOT) com wrote:
Quote:
#include <iostream
using std::cout;
using std::endl;
using std::ostream;

#include<map
using std::map;

Not related to your question, but this can be dangerous, since 'using'
issued before including a header affects that header (and any headers
that header include) which is not the intent. In this particular case
it's OK, but be warned.

[skipped]
Quote:
/* Class M to be used as part of map. */

class M {
public:
M() {};
M(int, vector<int>) {int i = 0; vector <int> table2;};

Again, not related to your question, but you probably want the effect
of this code here:

M(int, vector< int > const&): i(0) { }

This prevents copying of vector< int > parameter by using a const
reference instead of passing by value. It also uses member
initialization instead of assignment in the body of constructor.
Moreover, your version does not assign any value to the class member
M::i-- it initializes auto variable 'i', which is probably not the
intent.

Quote:
~M() {};
private:
int i;
vector<int> mv;
};

ostream& operator<<(ostream &output, const int &x, const map<int, M
&y) {
output << x << endl << y;
return output;
};


This will not work, since operator<< is binary operator and must take
exactly two arguments-- not less, not more.

Quote:
/* This will not work, a failed attempt.
ostream& operator<<(ostream &output, const &vector<int> mv ) {
output << x;
return output;
};
*/

Surely. This function will call itself, and again, and again Smile
(supposing 'x' is mistyped for 'mv' here)

Quote:
typedef map<int, M>::const_iterator con_it;

for( con_it x = map_test.begin(); x !=map_test.end(); ++x ) {
cout << x->first << endl << x->second << endl;
}
}

(not related again, but returning a value from the 'main' function can
be considered a good practice)

Here, 'x' is of type std::pair< int, M > (or eqivalent), so 'x->first'
is of type int and 'x->second' is of type M. Next, the line

Quote:
cout << x->first << endl << x->second << endl;

can be interpreted as (ignoring the return values and assuming they are
std::cout):

operator<<(cout, x->first);
operator<<(cout, endl);
operator<<(cout, x->second); // here is the catch
operator<<(cout, endl);

Your program does not define a proper operator for the third line.
This operator should have the following signature:

std::ostream& operator<<(std::ostream& out, M const& m);

Quote:
If I leave out this section:

typedef map<int, M>::const_iterator con_it;

for( con_it x = map_test.begin(); x !=map_test.end(); ++x ) {
cout << x->first << endl << x->second << endl;

The programme compiles and builds correctly. Once I add it in (without
the overloaded << operator), I have linker errors indicating that the
compiler cannot find an << operator that takes an int and a const "M."

As a work around, I've attempted to create an overloaded << operator to
accomodate my user defined map, but nothing seems to work correctly.
I've tried several things including:

1. Created two separate overloaded operators, one for the two parts of
the map: an int and a vector.

- There is already an overload for int type (and other built-in types)
in the standard library.
- Neither int nor vector can be considered the 'parts' of std::map<
int, M >. Here, int is a mapped type and class M is a mapped-to type.
The type 'vector' have nothing to do with std::map< int, M > construct.

Quote:
2. Created an overloaded << operator with the following parameters:
ostream, int, ostream and vector. (as const and non-const references)

This will not work too (see above).

Quote:
3. Created an overloaded << operator with the following parameters:
ostream, map.

This is basically not a bad place for your 'for' loop above, but does
not solve your very problem.

Quote:
Am I attempting something not capable of working, that is using a class
as a member of a map? If I remove the class and just build a simple
map with two ints as members, I have no trouble. I've spent several
days on this but am not making much progress and would like to move on
to hash tables and learn those.

You have no trouble with std::map< int, int >, since the overload of
operator<< for x->first is fitting x->second as well.


Thanks.
Alex


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