473,397 Members | 1,985 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,397 software developers and data experts.

STL: Map of List of Pointers

Ok, so I'm trying to code a map of lists of pointers to a class (that
contains a struct). Basically, the class holds the struct that I'm
populating, and there can be multiple of these. The declaration looks
like this:
map<int, list<my_class*> > map_test;

Now, how do I go about adding and accessing a new element to any given
list? How would I access the data? I did this with a list of
pointers, but can't figure out how to get the map into the equation.
My 'list' code looked like this:

#include <iostream>
#include <string>
#include <list>
#include <map>

using namespace std;

class ex_class
{
public:
struct
{
int num;
int num2;
} info;

int inc_num () {return ++info.num;}
int dec_num () {return --info.num;}
int add_nums () {return info.num + info.num2;}
void print_vals ()
{
cout << "num: " << info.num << " num2: " << info.num2 << "\n\n";
}
};

int main ()
{
list<ex_class*> class_list, anon_list;
list<ex_class*>::iterator class_it, anon_it;
map<int, list<ex_class*>> map_test;
ex_class classone;
classone.info.num = 40;
classone.info.num2 = 30;
classone.print_vals();
cout << classone.inc_num() << '\n';
cout << classone.inc_num() << '\n';
cout << classone.inc_num() << '\n';
cout << classone.inc_num() << '\n';
cout << classone.inc_num() << '\n';
cout << "Sum: " << classone.add_nums() << "\n\n";

class_list.push_back (&classone);
class_it=class_list.begin();
(*class_it)->info.num = 20;
(*class_it)->print_vals();

anon_list.push_back (new ex_class);
anon_it=anon_list.begin();
(*anon_it)->info.num = 33;
(*anon_it)->info.num2 = 77;
(*anon_it)->print_vals();

return 0;
}
Any help would be great!

Oct 20 '05 #1
6 24431

<gt*****@gmail.com> wrote in message
news:11**********************@g14g2000cwa.googlegr oups.com...
Ok, so I'm trying to code a map of lists of pointers to a class (that
contains a struct). Basically, the class holds the struct that I'm
populating, and there can be multiple of these. The declaration looks
like this:
map<int, list<my_class*> > map_test;

Now, how do I go about adding and accessing a new element to any given
list? How would I access the data? I did this with a list of
pointers, but can't figure out how to get the map into the equation.
My 'list' code looked like this:

#include <iostream>
#include <string>
#include <list>
#include <map>
#include <utility>

using namespace std;

class ex_class
{
public:
struct
{
int num;
int num2;
} info;

int inc_num () {return ++info.num;}
int dec_num () {return --info.num;}
int add_nums () {return info.num + info.num2;}
void print_vals ()
{
cout << "num: " << info.num << " num2: " << info.num2 << "\n\n";
}
};

int main ()
{
list<ex_class*> class_list, anon_list;
list<ex_class*>::iterator class_it, anon_it;
map<int, list<ex_class*>> map_test;
This line won't compile. Make it:

map<int, list<ex_class*> > map_test;
ex_class classone;
classone.info.num = 40;
classone.info.num2 = 30;
classone.print_vals();
cout << classone.inc_num() << '\n';
cout << classone.inc_num() << '\n';
cout << classone.inc_num() << '\n';
cout << classone.inc_num() << '\n';
cout << classone.inc_num() << '\n';
cout << "Sum: " << classone.add_nums() << "\n\n";

class_list.push_back (&classone);
class_it=class_list.begin();
(*class_it)->info.num = 20;
(*class_it)->print_vals();

anon_list.push_back (new ex_class);
anon_it=anon_list.begin();
(*anon_it)->info.num = 33;
(*anon_it)->info.num2 = 77;
(*anon_it)->print_vals();
map_test.insert(pair<int, list<ex_class*> >(42, class_list));
map_test.insert(pair<int, list<ex_class*> >(99, anon_list));

list<ex_class*>::const_iterator it(map_test[42].begin());
cout << (**it).info.num << '\n';

/* 42 and 99 are arbitrary values */

-Mike

return 0;
}
Any help would be great!

Oct 20 '05 #2
Mike-
Thanks for the speedy reply, and help. I have two more questions. Is
there a way to do something like this so I wouldn't have to use an
intermediate object? (I know this probably doesn't compile,it's just an
example to give you an idea of what I want to do):

map_test.insert(pair<int, list<ex_class*> >(43, new ex_class);

Also, how would I reference the struct in the class?

Oct 21 '05 #3

"gthorne" <gt*****@gmail.com> wrote in message
news:11*********************@g43g2000cwa.googlegro ups.com...
Mike-
Thanks for the speedy reply, and help. I have two more questions. Is
there a way to do something like this so I wouldn't have to use an
intermediate object? (I know this probably doesn't compile,it's just an
example to give you an idea of what I want to do):

map_test.insert(pair<int, list<ex_class*> >(43, new ex_class);
You can't do that because the second template parameter is
a pointer to a list, not a pointer to an 'ex_class'. Also
note that this still uses an 'intermediate' (more formally,
a 'temporary') object, that is, the pointer object returned
by the 'new' operator
However you could first insert empty lists into your map,
and then insert 'ex_class' objects into those lists after
the fact.

Also, how would I reference the struct in the class?


See the last 'cout' statement in my example.

(BTW, in my last post, I forget to
advise you that you should 'delete' any objects which you've
allocate with 'new', when done with them. Your code you
posted did not do that).

-Mike
Oct 21 '05 #4
"gthorne" <gt*****@gmail.com> wrote in message
news:11*********************@g43g2000cwa.googlegro ups.com...
Is
there a way to do something like this so I wouldn't have to use an
intermediate object? (I know this probably doesn't compile,it's just an
example to give you an idea of what I want to do):

map_test.insert(pair<int, list<ex_class*> >(43, new ex_class);


First, I suggest that you get into the habit of using typedefs to make your
code more clear. This would also avoid your earlier error that was corrected
by Mike Wahler.

class Foo{ /* ... */};

typedef list<Foo*> Foos;
typedef map<int, Foos> FoosDictionary;

Adding make_pair to this, we get a much more readable code:

Foos anon_foos;
FoosDictionary foosDictionary;
foosDictionary.insert(make_pair(42, anon_foos));

As you've observed, this takes a copy of anon_foos and stores that copy in
the dictionary. In order to get what you asked, write a function that
returns an ex_class*, and call it when calling make_pair:

ex_class * prepare_ex_class(/* ... */)
{
ex_class * object = new ex_class(/* ... */);
// do other things to object ...
return object;
}

Then, when you insert:

map_test.insert(make_pair(43, prepare_ex_class(/* ... */));

But then you should change the definition of the dictionary:

typedef map<int, Foos *> FoosDictionary;

Be warned though, these are not exception safe. A common safe way of storing
dynamic objects in standard containers is to store smart pointers instead of
plain pointers. Even your list<Foo*> could benefit from a smart pointer:

#include <boost/shared_ptr.hpp>

using namespace boost;

/* ... */

typedef shared_ptr<Foo> FooPtr;
typedef list<FooPtr> Foos;
typedef shared_ptr<Foos> FoosPtr;
typedef map<int, FoosPtr> FoosDictionary;

// etc. :)

Ali

Oct 21 '05 #5
Ali/Mike-
Thanks for your great replies. As for 'delete' and the typedefs, those
are coming. What I posted above was just sample code that I was
tinkering with to get this to work.

Do you think it may be better to put the list inside of the class?
Basically, without getting into the specific (i.e. 'boring') business
need for this code, think of it as a grocery store checkout (that's not
what it is, but it's a good example). The class holds the information
for one item. The list is the multiple items that the cashier is
ringing up, and the map is the multiple lanes. Should it be 'map of
lists of pointers to classes containing a struct', or 'map of pointers
to classes containing lists of structs'?

You guys have been a great help, and I appreciate it very much.

Oct 21 '05 #6
"gthorne" <gt*****@gmail.com> wrote in message
news:11**********************@f14g2000cwb.googlegr oups.com...
As for 'delete' and the typedefs, those
are coming.
Note that, if you go the smart pointer route, you highly likely won't need
to delete explicitly. boost::shared_ptr, which is also a standard library
feature after TR1, deletes the objects it owns automatically.

As for the class design, given what you describe, I picture it as the
following:
The class holds the information
for one item.
class Item {/* ... */};
The list is the multiple items that the cashier is
ringing up,
Simply:

typedef list<Item> GroceryBag;

or, if it needs more logic:

class GroceryBag
{
list<Item> items_;
Color color_; // "colour" works too :)
// etc.

/* ... */
};
and the map is the multiple lanes.
class Cashier
{
/* ... */

public:

void process(GroceryBag const & groceryBag);

/* ... */
};

typedef map<int, Cashier> Cashiers;

class Shopper
{
GroceryBag bag_;

/* ... */

public:

void check_out(Cashier const & cashier)
{
cashier.process(bag_);
}
};

Cashier & least_busy_cashier(Cashiers & cashiers)
{
return /* one of the cashiers */
}

customer.check_out(least_busy_cashier(cashiers));
Should it be 'map of
lists of pointers to classes containing a struct', or 'map of pointers
to classes containing lists of structs'?


I don't see any reason for pointers in what you described.

Ali

Oct 21 '05 #7

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

4
by: Asapi | last post by:
class base { }; class d1 : public base { }; class d2 : public base {
2
by: Barry Hynes | last post by:
G'Day folks, Have been working on this problem for quite some time and still no farther ahead. :( Here is my problem...bare with me i am very green :) I have to implement a Safe List,...
2
by: Jim Strathmeyer | last post by:
I have a weird question about const correctness when using an stl list. I have a wrapper Inventory class that holds a list of pointers to Items. (Yes, they have to be pointers.) Now, obviously...
4
by: Christian Christmann | last post by:
Hi, I need an STL list and was thinking of putting the list in wrapper class. The reason for my decision is that you can much better perform consistency checks. For instance, I need a...
8
by: cpptutor2000 | last post by:
I am using an STL list to store data packets in a network simulator. The data packets are really C structs, which have other C structs inside them. These structs contain unsigned char arrays of...
5
by: Allerdyce.John | last post by:
In STL list, is it safe to do this: list<A> aList; //private attribute of MyClass void MyClass:: aMethod() { list<A>::Iterator iter; for ( iter = aList.begin() ; iter != aList.end() ;...
6
by: Jonathan | last post by:
Hi. I'm having trouble figuring out what I should be doing here. I'm trying to remove an object from a list. The function is: void Alive::FromRoom () { list<Alive>::iterator iter =...
3
by: Christian Christmann | last post by:
Hi, reading the output of gprof for one of my projects, I found that the STL list assignment operator consumes a larger fraction of the program's execution time. The exact entry in gprof's...
27
by: Jason Doucette | last post by:
I'm getting an assertion fire from a list iterator being checked against NULL. This did not occur in VC++ 2003 (v7.1). Are there changes that have been made to the STL between these versions that...
2
by: harsh.murari | last post by:
I wanted to know how the C++ STL list is implemented. Specifically, I wanted to understand the memory usage by the list objects. I have the following code snippet: std::list <intL; ...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.