Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
303 views
in Technique[技术] by (71.8m points)

list - How to make the for each loop function in C++ work with a custom class

I'm new to C/C++ programming, but I've been programming in C# for 1.5 years now. I like C# and I like the List class, so I thought about making a List class in C++ as an exercise.

List<int> ls;
int whatever = 123;
ls.Add(1);
ls.Add(235445);
ls.Add(whatever);

The implementation is similar to any Array List class out there. I have a T* vector member where I store the items, and when this storage is about to be completely filled, I resize it.

Please notice that this is not to be used in production, this is only an exercise. I'm well aware of vector<T> and friends.

Now I want to loop through the items of my list. I don't like to use for(int i=0;i<n; i==). I typed for in the visual studio, awaited for Intellisense, and it suggested me this:

for each (object var in collection_to_loop)
{

}        

This obviously won't work with my List implementation. I figured I could do some macro magic, but this feels like a huge hack. Actually, what bothers me the most is passing the type like that:

#define foreach(type, var, list)
int _i_ = 0;
##type var;
for (_i_ = 0, var=list[_i_]; _i_<list.Length();_i_++,var=list[_i_]) 

foreach(int,i,ls){
    doWork(i);
}

My question is: is there a way to make this custom List class work with a foreach-like loop?

question from:https://stackoverflow.com/questions/65545927/enabling-range-based-for-loop-on-class-composed-for-2-or-more-stl-containers

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Firstly, the syntax of a for-each loop in C++ is different from C# (it's also called a range based for loop. It has the form:

for(<type> <name> : <collection>) { ... }

So for example, with an std::vector<int> vec, it would be something like:

for(int i : vec) { ... }

Under the covers, this effectively uses the begin() and end() member functions, which return iterators. Hence, to allow your custom class to utilize a for-each loop, you need to provide a begin() and an end() function. These are generally overloaded, returning either an iterator or a const_iterator. Implementing iterators can be tricky, although with a vector-like class it's not too hard.

template <typename T>
struct List
{
    T* store;
    std::size_t size;
    typedef T* iterator;
    typedef const T* const_iterator;

    ....

    iterator begin() { return &store[0]; }
    const_iterator begin() const { return &store[0]; }
    iterator end() { return &store[size]; }
    const_iterator end() const { return &store[size]; }

    ...
 };

With these implemented, you can utilize a range based loop as above.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...