Sign in to follow this  
Pendu

Need help with containers

Recommended Posts

Pendu    145
public void draw_all_vec(vector<int> const vec) { for(int x = 0; x <vec.size();++x) { cout vec[x]; } } How i would i generalise this for all types of containers not just vectors. Would i need to use a template method, if so how would you use a template method to generalise a container.

Share this post


Link to post
Share on other sites
SiCrane    11839
You would do something like:

template <typename Container>
void draw_all(const Container & container) {
for (typename Container::iterator itr = container.begin();
itr != container.end();
++itr) {
// draw with *itr
}
}

Share this post


Link to post
Share on other sites
Metorical    580
Do you want to be able to 'draw' any object type or is there a subset of objects that should be drawable?

Have you considered using a base drawable class with a pure virtual draw function. Then anything that must be drawable can inherit from this class and define a function that tells the system how to draw it?

Then you can have pointers to all your drawable objects and simply loop through them and call the draw function.

Share this post


Link to post
Share on other sites
dave    2187

template <typename Container>
void draw_all(const Container & container) {
for (typename Container::iterator itr = container.begin();
itr != container.end();
++itr) {
// draw with *itr
}
}

This could be written a llittle better as:

template <typename Container>
void draw_all(const Container & container) {
typename Container::iterator iter, begin, end;

begin = container.begin();
end = container.end();

for (itr = begin;
itr != end();
++itr) {
// draw with *itr
}
}

You could even use const_iterator if you know that you are not changing the state of the object contained.

ace

Share this post


Link to post
Share on other sites
Zahlman    1682
Another option is to accept a pair of iterators. This complicates the interface a bit, in exchange for the ability to output ranges of a container (rather than always having to use the whole thing).


template <typename InputIterator>
void draw_all(const InputIterator& begin, const InputIterator& end) {
for (InputIterator it = begin; it != end; ++it) {
// draw with *itr
}
}

//...
draw_all(myVector.begin(), myVector.end());
draw_all(myMap.find("foo"), myMap.find("quux"));
// Actually, because the map iterators will be iterators over key/value pairs
// and you presumably want to 'draw with' just the value, you will probably
// need a specialization in that case :/


This can also be done with std::algorithms:


#include <algorithm>
using namespace std;

struct draw {
void operator() (const Thing& t) {
thing.draw(); // invoke Thing::draw() const
}
};
// ...
Vector<Thing> myVector;
// ...
// Create a draw object; the for_each will invoke its operator() with each
// item in the range.
for_each(myVector.begin(), myVector.end(), draw());

// Or if we just want to output Things using
// operator<< (ostream&, const Thing&):
copy(myVector.begin(), myVector.end(), ostream_iterator<Thing>(cout, ""));
// The "" can be any string literal; it is used as a separator between
// output items.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this