轉載:在C++中實現(xiàn)foreach循環(huán)
使用過C#、PHP這些更高級語言的朋友一定知道foreach循環(huán)。foreach語句給編程帶來了很大的方便,減少了代碼,并增加了程序的可讀性。C++雖然不支持foreach關鍵字,但C++是一門強大的語言,只要稍微用一點小技巧,也可以在C++中使用foreach循環(huán)。
在C#中,foreach語句的效果讓人吃驚。foreach語句省去了復雜而又類似的循環(huán)控制語句,使代碼非常簡潔明了。下面的例子可以清楚地看到這一點。
假有一個類型為ContainerType類型的容器Container,它的每個元素的類型為ElementType。
在C#中,數(shù)組就是這樣一種容器。
在C++中,stl的vector、map等也是這樣的容器。
如果要遍歷容器Container的每個元素,在C#中可以使用如下代碼:
而在C++中,通常的代碼都會是這樣:
顯然C#中的代碼更清晰的多。而C++的代碼中包含了變量聲明和循環(huán)控制,顯得更復雜了。也許您對這一點增加的復雜性并不在意,但本著勿因善小而不為的原則,以及一點思考精神,我決定讓C++也擁有使用foreach循環(huán)的能力。
C++的宏很適合做這種事情。問題在于如何做的更像C#中的那種樣式。如果在訪問元素的代碼塊的前面和后面各加一個宏,那么這件事情就變得毫無意義,并很可笑。
我們只能使用一個宏,并命名為foreach。在這個宏后面的代碼塊將可以像在C#中那樣可以使用一個變量名來遍歷容器中的所有元素。宏中聲明的變量不能污染到程序中其它部分的命名間,而這些變量又不在訪問元素的代碼塊中聲明。這樣的要求使這個問題變成一種考驗代碼技巧的有趣問題。
C++語言控制能力的強大使它確實可以支持foreach語句。這要用到兩個技巧:1,for循環(huán)的第一條語句可以聲明局部變量;2,充分利用for循環(huán)的過程控制能力。
C++中的foreach語句定義宏如下:
宏中定義了三重for循環(huán)。第一重的意義很清楚:使用容器的遍歷者遍歷容器中的元素。第二、第三重for循環(huán)其實只能執(zhí)行一次,其主要目的是聲明element變量。C++的變量引用類型使后面的元素訪問代碼塊可以直接使用element變量。
foreach宏的參數(shù)依次為:元素類型,元素名,容器類型,容器名。
假設有個vector如下面的定義:
vector<int> v;
那么遍歷v可以使用下面的代碼:
是不是很像C#中的foreach語句呢?我寫了一小段程序,看看這個宏是不是真的能工作,代碼如下:
結果輸出很正確!
事實上,在C++中,for語句以及其它語句,它們的本質是基于計算機指令的過程控制語句,而C#中的foreach語句,可以看作是基遍歷者這種設計模式的語句。編程語言從只基于計算機指令到基于設計模式,這應該也算是軟件發(fā)展的進步吧。
在C++中使用文中定義的foreach語句并不能提高程序的效率,也不會明顯降低效率。foreach宏只能在代碼層面上有些好處,減少一些重復的代碼,增加一點可讀性。設計這個宏,就當是個趣味技巧題,玩一玩,并支持一下那些堅決擁抱C++的朋友們。
作者:蘇林
使用過C#、PHP這些更高級語言的朋友一定知道foreach循環(huán)。foreach語句給編程帶來了很大的方便,減少了代碼,并增加了程序的可讀性。C++雖然不支持foreach關鍵字,但C++是一門強大的語言,只要稍微用一點小技巧,也可以在C++中使用foreach循環(huán)。
在C#中,foreach語句的效果讓人吃驚。foreach語句省去了復雜而又類似的循環(huán)控制語句,使代碼非常簡潔明了。下面的例子可以清楚地看到這一點。
假有一個類型為ContainerType類型的容器Container,它的每個元素的類型為ElementType。
在C#中,數(shù)組就是這樣一種容器。
在C++中,stl的vector、map等也是這樣的容器。
如果要遍歷容器Container的每個元素,在C#中可以使用如下代碼:
foreach( ElementType element in Container)
{ // 使用element訪問該元素
}
{ // 使用element訪問該元素
}
而在C++中,通常的代碼都會是這樣:
Container::iterator iter;
for (iter = Container.begin(); iter!=Container.end(); iter++)
{ // 使用(*iter)訪問該元素
}
for (iter = Container.begin(); iter!=Container.end(); iter++)
{ // 使用(*iter)訪問該元素
}
顯然C#中的代碼更清晰的多。而C++的代碼中包含了變量聲明和循環(huán)控制,顯得更復雜了。也許您對這一點增加的復雜性并不在意,但本著勿因善小而不為的原則,以及一點思考精神,我決定讓C++也擁有使用foreach循環(huán)的能力。
C++的宏很適合做這種事情。問題在于如何做的更像C#中的那種樣式。如果在訪問元素的代碼塊的前面和后面各加一個宏,那么這件事情就變得毫無意義,并很可笑。
我們只能使用一個宏,并命名為foreach。在這個宏后面的代碼塊將可以像在C#中那樣可以使用一個變量名來遍歷容器中的所有元素。宏中聲明的變量不能污染到程序中其它部分的命名間,而這些變量又不在訪問元素的代碼塊中聲明。這樣的要求使這個問題變成一種考驗代碼技巧的有趣問題。
C++語言控制能力的強大使它確實可以支持foreach語句。這要用到兩個技巧:1,for循環(huán)的第一條語句可以聲明局部變量;2,充分利用for循環(huán)的過程控制能力。
C++中的foreach語句定義宏如下:
#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)
for (containerType::iterator iter = container.begin(); iter != container.end(); iter++)"
for (bool go = true; go;)"
for (elementType & element = *iter;go; go=false)
宏中定義了三重for循環(huán)。第一重的意義很清楚:使用容器的遍歷者遍歷容器中的元素。第二、第三重for循環(huán)其實只能執(zhí)行一次,其主要目的是聲明element變量。C++的變量引用類型使后面的元素訪問代碼塊可以直接使用element變量。
foreach宏的參數(shù)依次為:元素類型,元素名,容器類型,容器名。
假設有個vector如下面的定義:
vector<int> v;
那么遍歷v可以使用下面的代碼:
foreach(int, e, vector<int>, v)
{//使用(e)來訪問v的元素
}
{//使用(e)來訪問v的元素
}
是不是很像C#中的foreach語句呢?我寫了一小段程序,看看這個宏是不是真的能工作,代碼如下:
#include <iostream>
#include <vector>
using namespace std;
// 在C++中使用 foreach 循環(huán)
#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) // 在這里使用foreach語句
{
printf("%d"n", e);
}
}
#include <vector>
using namespace std;
// 在C++中使用 foreach 循環(huán)
#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) // 在這里使用foreach語句
{
printf("%d"n", e);
}
}
結果輸出很正確!
事實上,在C++中,for語句以及其它語句,它們的本質是基于計算機指令的過程控制語句,而C#中的foreach語句,可以看作是基遍歷者這種設計模式的語句。編程語言從只基于計算機指令到基于設計模式,這應該也算是軟件發(fā)展的進步吧。
在C++中使用文中定義的foreach語句并不能提高程序的效率,也不會明顯降低效率。foreach宏只能在代碼層面上有些好處,減少一些重復的代碼,增加一點可讀性。設計這個宏,就當是個趣味技巧題,玩一玩,并支持一下那些堅決擁抱C++的朋友們。
作者:蘇林