Example of implementing a Foreach loop in C + +

Source: Internet
Author: User
Tags foreach function prototype

Python,c#,java inside are similar to the structure of a foreach, STL inside although there is for_each this function, but feel the use is still too cumbersome some, so I realized one. First look at the STL inside the For_each function, the official document on the prototype is as follows:

function For_each (inputiterator, inputiterator, function f);

The sample code is as follows:

For_each Example
#include <iostream>
#include <algorithm>
#include <vector>
using namespace Std;

void MyFunction (int i) {
cout << "" << i;
}

struct MyClass {
void operator () (int i) {cout << "" << I;}
} MyObject;

int main () {
Vector<int> Myvector;
Myvector.push_back (10);
Myvector.push_back (20);
Myvector.push_back (30);

cout << "myvector contains:";
For_each (Myvector.begin (), Myvector.end (), myfunction);

Or
cout << "\nmyvector contains:";
For_each (Myvector.begin (), Myvector.end (), MyObject);

cout << Endl;

return 0;
}
Not only is a function prototype a bit of a habit, but it's also a bit tedious to write a function, which is a little cumbersome compared to how Python is implemented:

For D in L:
Print D

We're going to do this on our own, it's definitely a macro, let's take a look at the first version:

#define foreach (Container,it,type) \
for (Type::iterator it = (container). Begin (), it!= (container). end (); ++it)

The sample code is as follows:

#include <iostream>
#include <string>
#include <vector>
#include <set>
#include <map>
using namespace Std;

#define foreach (Container,it,type) \
for (Type::iterator it = (container). Begin (), it!= (container). end (); ++it)

int main (int argc, const char *argv[])
{
Set<string> s;
S.insert ("w");
S.insert ("a");
S.insert ("n");


foreach (s,it,set<string>)
{
cout<<*it<<endl;
}

/*map<unsigned,string> m;
m[0]= "X";
M[1]= "W";

foreach (m,it,map<unsigned,string>)
{
cout<<it->first<< "," <<it->second<<endl;
}*/

return 0;
}

If you open the commented out code, it will be an error, should be the macro can not handle the reason for the comma.
And it's a little cumbersome to call, right, Python doesn't require incoming container types, can we dispense with the set parameter?
Let's take a look at this piece of code:

typeof (a);
A = 100;
cout<<a<<endl;
This code can be executed, and the result of the operation is 100. From this point, can we get the container type through typeof (container) and then pass typeof (Container):: Iterator to create the traversal pointer, let's look at the second version

#define foreach (container,it) \
For (typeof (Container):: Iterator it = (container). Begin (), it!= (container). end (); ++it)
Unfortunately, however, this code is not able to run, the results of the compilation are as follows:

test4.cpp|21| error:expected initializer before "it"
test4.cpp|21| Error: ' It ' wasn't declared in this scope
test4.cpp|34| error:expected initializer before "it"
test4.cpp|34| Error: ' It ' wasn't declared in this scope
Is there any way to solve it?
Yes, we use a curve to save the nation's way! typeof (Container.begin ()), haha! The final code is as follows:


#define foreach (container,it) \
For (typeof (Container). Begin ()) it = (container). Begin (), it!= (container). end (); ++it)
The test code is as follows:


#include <vector>
#include <set>
#include <map>
using namespace Std;

#define foreach (container,it) \
For (typeof (Container). Begin ()) it = (container). Begin (), it!= (container). end (); ++it)

int main (int argc, const char *argv[])
{
Set<string> s;
S.insert ("w");
S.insert ("a");
S.insert ("n");


foreach (S,it)
{
cout<<*it<<endl;
}

Map<unsigned,string> m;
m[0]= "X";
M[1]= "W";

foreach (M,it)
{
cout<<it->first<< "," <<it->second<<endl;
}

return 0;
}
Enter the results as follows:

A
N
W
0,x
1,w
Ok! Everything's fine! This should be a simpler version of the form, if you have any better suggestions, welcome message exchange ~
Ps:
Of course, you can dispense with it, but according to the principle of pythonic (OK, I know I am writing C + +), to simple but not confusing, so it is recommended to keep it this parameter.

Add:

False has a container container type Containertype type, each element of which is of type ElementType.
In C #, arrays are such a container.
In C + +, the vector of the STL, map, and so on are such containers.
If you want to traverse each element of the container container, you can use the following code in C #:
foreach (elementtype element in Container)
{//access to this element using element
}
In C + +, the usual code would be this:
Container::iterator ITER;
for (iter = Container.begin (); Iter!= container.end (); iter + +)
{//Use (*iter) to access this element
}

Obviously, the code in C # is much clearer. The C + + code contains variable declarations and loop control, which is more complicated. Perhaps you don't care about the added complexity of this, but with the principle of not being good and small, and a little bit of thinking, I decided to let C + + also have the ability to use a Foreach loop.

C + + macros are good for this kind of thing. The problem is how to do it more like the style in C #. If you add a macro to the front and back of the code block that accesses the element, then this thing becomes meaningless and ridiculous.

We can only use one macro and name it foreach. The code block behind this macro will be able to use a variable name to traverse all elements in the container, as in C #. Variables declared in a macro cannot contaminate the names of other parts of the program, which are not declared in the code block that accesses the element. Such a requirement makes this question an interesting question that tests code skills.

The ability to control the C + + language enables it to really support the foreach statement. This takes two tricks: the first statement of the 1,FOR Loop can declare a local variable, 2, taking full advantage of the process control capabilities of the For loop.

The foreach statement in C + + defines the macro as follows:
#define foreach (ElementType, Element, Containertype, container)
for (containertype::iterator iter = container. Begin (), ITER!= container. End (); iter + +)/
for (bool go = true; Go;)/
for (ElementType & element = * ITER; go; Go = False)
A triple for loop is defined in the macro. The first importance is clear: Use the container's traversal to traverse the element in the container. The second, third, the For loop can only be executed once, and its primary purpose is to declare the element variable. The variable reference type of C + + enables the subsequent element access code block to use the element variable directly.

The parameters of the foreach macro are: element type, element name, container type, container name.

Suppose there's a vector like the following definition:
Vector<int > V;

So traversing V can use the following code:
foreach (int, E, vector<int, V)
{///use (e) to access the elements of V
}

Is it like a foreach statement in C #? I wrote a short program to see if the macro really worked, and the code was as follows:


#include <iostream>
#include <vector>
using namespace Std;

Using a Foreach loop in C + +
#define foreach (ElementType, Element, Containertype, container)
for (Containertype::iterator iter = Container.begin (); Iter!= container.end (); iter++)/
for (bool go = true; go;)/
for (ElementType & element = *iter;go; go=false)

int main ()
{
Vector<int > V;
for (int i=0; i<10; ++i)
V.push_back (i);
foreach (int, E, vector<int, v)//Use the foreach statement here
{
printf ("%d/n", e);
}
}

The result output is correct!

In fact, in C + +, for statements and other statements, their essence is a Process Control statement based on a computer instruction, and a foreach statement in C # can be viewed as a statement of the design pattern of the base traversal. Programming languages are based on computer commands only to design patterns, which should be a step forward in software development.

Using the foreach statement defined in the text in C + + does not increase the efficiency of the program, nor does it significantly reduce efficiency. A foreach macro can only have some benefit at the code level, reducing some duplicate code and adding a little readability. Design this macro, as a fun trick, play, and support those who firmly embrace C + + friends.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.