By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
446,227 Members | 1,290 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 446,227 IT Pros & Developers. It's quick & easy.

A Forward Iterator type / class?

P: n/a
Hi,

I have a Display class. I would like to write a function that takes a
range of objects and displays them. The range would be specified by
two forward iterators: start and end (one past start).

I created a base class "References" to test this concept. I want
the display function to process either a vector<References> or
a list<References>. However, in my compiler (Borland C++ Builder),
the std::list has a different iterator type than vector.

So how can I write a method to process a range of objects,
regardless of the container (assume that the fundamental requirement
for a range is forward iteration)?

struct Reference
{
string get_category(void) const;
string get_title(void) const;
};

class User_Interface
// : public Singleton<User_Interface>
// i.e. User_Interface is a Singleton
{
void display_references(?????);
};

User_Interface My_UI;

int main(void)
{
std::list<Reference> ref_list;
std::vector<Reference> ref_vector;

My_UI.display_references(ref_list.begin(),
ref_list.end());
My_UI.display_references(ref_vector.begin(),
ref_vector.end());
}

The above code is for illustrative purposes only and is
not meant to be compiled or run without errors.

--
Thomas Matthews

C++ newsgroup welcome message:
http://www.slack.net/~shiva/welcome.txt
C++ Faq: http://www.parashift.com/c++-faq-lite
C Faq: http://www.eskimo.com/~scs/c-faq/top.html
alt.comp.lang.learn.c-c++ faq:
http://www.raos.demon.uk/acllc-c++/faq.html
Other sites:
http://www.josuttis.com -- C++ STL Library book

Jul 22 '05 #1
Share this Question
Share on Google+
5 Replies


P: n/a
Thomas Matthews wrote:
Hi,

I have a Display class. I would like to write a function that takes a
range of objects and displays them. The range would be specified by
two forward iterators: start and end (one past start).
Didn't you mean one past _end_?
I created a base class "References" to test this concept. I want
the display function to process either a vector<References> or
a list<References>. However, in my compiler (Borland C++ Builder),
the std::list has a different iterator type than vector.
That's not surprising.
So how can I write a method to process a range of objects,
regardless of the container (assume that the fundamental requirement
for a range is forward iteration)?
Use templates.
struct Reference
{
string get_category(void) const;
string get_title(void) const;
};

class User_Interface
// : public Singleton<User_Interface>
// i.e. User_Interface is a Singleton
{
void display_references(?????);
template <typename Iter>
void display_references(Iter begin, Iter end);
};

User_Interface My_UI;

int main(void)
{
std::list<Reference> ref_list;
std::vector<Reference> ref_vector;

My_UI.display_references(ref_list.begin(),
ref_list.end());
My_UI.display_references(ref_vector.begin(),
ref_vector.end());
}

The above code is for illustrative purposes only and is
not meant to be compiled or run without errors.


Jul 22 '05 #2

P: n/a
Thomas Matthews wrote in news:I8mEb.37689$Kh6.35485
@newssvr32.news.prodigy.com:

[sniping...]
.... However, in my compiler (Borland C++ Builder),
the std::list has a different iterator type than vector.

So how can I write a method to process a range of objects,
regardless of the container (assume that the fundamental requirement
for a range is forward iteration)?

Use a template member function:
struct Reference
{ };

class User_Interface {
template < typename Iter >
void display_references( Iter ptr, Iter Lim );
void display_references(?????);
};
template < typename Iter >
void User_Interface::display_references( Iter ptr, Iter Lim )
{

}
User_Interface My_UI;

int main(void)
{ My_UI.display_references(ref_list.begin(),
ref_list.end());
My_UI.display_references(ref_vector.begin(),
ref_vector.end());
}

The above code is for illustrative purposes only and is
not meant to be compiled or run without errors.


Rob.
--
http://www.victim-prime.dsl.pipex.com/
Jul 22 '05 #3

P: n/a
Thomas Matthews wrote:
Hi,

I have a Display class. I would like to write a function that takes a
range of objects and displays them. The range would be specified by
two forward iterators: start and end (one past start).

I created a base class "References" to test this concept. I want
That's a potentially confusing choice of name. "Reference" already
means something completely different. Consider "Proxy" instead.
the display function to process either a vector<References> or
a list<References>. However, in my compiler (Borland C++ Builder),
the std::list has a different iterator type than vector.

So how can I write a method to process a range of objects,
regardless of the container (assume that the fundamental requirement
for a range is forward iteration)?

struct Reference
{
string get_category(void) const;
string get_title(void) const;
};

class User_Interface
// : public Singleton<User_Interface>
// i.e. User_Interface is a Singleton
{
void display_references(?????);
The answer to the question you asked, is: Make the type of the
iterators a template parameter. E.g.:

template< typename For /* forward iterator */ >
void display_references( For p, For const& end )
{
// Do your thing...
}

The answer to the question you didn't ask is: Don't reinvent the loop.
Use std::for_each. E.g.:

std::for_each( list.begin( ), list.end( ), display );

std::for_each( vector.begin( ), vector.end ), display );

Hth,
Jeff

};

User_Interface My_UI;

int main(void)
{
std::list<Reference> ref_list;
std::vector<Reference> ref_vector;

My_UI.display_references(ref_list.begin(),
ref_list.end());
My_UI.display_references(ref_vector.begin(),
ref_vector.end());
}

The above code is for illustrative purposes only and is
not meant to be compiled or run without errors.


Jul 22 '05 #4

P: n/a
Jeffrey Schwab wrote:
Thomas Matthews wrote:
Hi,

I have a Display class. I would like to write a function that takes a
range of objects and displays them. The range would be specified by
two forward iterators: start and end (one past start).

I created a base class "References" to test this concept. I want

That's a potentially confusing choice of name. "Reference" already
means something completely different. Consider "Proxy" instead.

My base class is "Reference". Subclasses are Magazine, Book, etc.
Nothing to do with C++ references or proxies.

the display function to process either a vector<References> or
a list<References>. However, in my compiler (Borland C++ Builder),
the std::list has a different iterator type than vector.

So how can I write a method to process a range of objects,
regardless of the container (assume that the fundamental requirement
for a range is forward iteration)?

struct Reference
{
string get_category(void) const;
string get_title(void) const;
};

class User_Interface
// : public Singleton<User_Interface>
// i.e. User_Interface is a Singleton
{
void display_references(?????);

The answer to the question you asked, is: Make the type of the
iterators a template parameter. E.g.:

template< typename For /* forward iterator */ >
void display_references( For p, For const& end )
{
// Do your thing...
}

The answer to the question you didn't ask is: Don't reinvent the loop.
Use std::for_each. E.g.:

std::for_each( list.begin( ), list.end( ), display );

std::for_each( vector.begin( ), vector.end ), display );

Hth,
Jeff

Personally, I don't see any gain in efficiency or readability with
the std::for_each algorithm; but that is my opinion.

--
Thomas Matthews

C++ newsgroup welcome message:
http://www.slack.net/~shiva/welcome.txt
C++ Faq: http://www.parashift.com/c++-faq-lite
C Faq: http://www.eskimo.com/~scs/c-faq/top.html
alt.comp.lang.learn.c-c++ faq:
http://www.raos.demon.uk/acllc-c++/faq.html
Other sites:
http://www.josuttis.com -- C++ STL Library book

Jul 22 '05 #5

P: n/a
Thomas Matthews wrote:
Jeffrey Schwab wrote:
Thomas Matthews wrote:
Hi,

I have a Display class. I would like to write a function that takes a
range of objects and displays them. The range would be specified by
two forward iterators: start and end (one past start).

I created a base class "References" to test this concept. I want


That's a potentially confusing choice of name. "Reference" already
means something completely different. Consider "Proxy" instead.


My base class is "Reference". Subclasses are Magazine, Book, etc.
Nothing to do with C++ references or proxies.


See how misleading the name was? :)

The nature of the class might be clear from context to anyone reading
your complete program, but I still think you have to be the kind of
person who kicks puppies to name a class "Reference."
the display function to process either a vector<References> or
a list<References>. However, in my compiler (Borland C++ Builder),
the std::list has a different iterator type than vector.

So how can I write a method to process a range of objects,
regardless of the container (assume that the fundamental requirement
for a range is forward iteration)?

struct Reference
{
string get_category(void) const;
string get_title(void) const;
};

class User_Interface
// : public Singleton<User_Interface>
// i.e. User_Interface is a Singleton
{
void display_references(?????);


The answer to the question you asked, is: Make the type of the
iterators a template parameter. E.g.:

template< typename For /* forward iterator */ >
void display_references( For p, For const& end )
{
// Do your thing...
}

The answer to the question you didn't ask is: Don't reinvent the
loop. Use std::for_each. E.g.:

std::for_each( list.begin( ), list.end( ), display );

std::for_each( vector.begin( ), vector.end ), display );

Hth,
Jeff


Personally, I don't see any gain in efficiency or readability with
the std::for_each algorithm; but that is my opinion.


Well, how about the fact that it would have obviated your original post
entirely, and you never would have had the any problem using multiple
types of iterators? Or, how about the fact that for_each saves you from
having to write the looping code? Or, how about the fact that the
program is shorter? Or... maybe we can just agree to disagree.

-Jeff

Jul 22 '05 #6

This discussion thread is closed

Replies have been disabled for this discussion.