2008-10-13 57 views
23

我只是最近才發現,Visual C++ 2008(也許還有更早的版本?)支持stl lists et al上的for each語法來促進迭代。 例如:Visual c + +「每個」可移植性

list<Object> myList; 

for each (Object o in myList) 
{ 
    o.foo(); 
} 

我很高興地發現它,但我很擔心可移植性可怕的一天,當有人決定我需要能夠編譯我的代碼中說,海灣合作委員會或其他一些編譯器。這種語法是否得到廣泛支持,我可以使用它,而不必擔心可移植性問題?

回答

21

有一個非常好的便攜式替代品:Boost.Foreach。只轉儲這頭到你的項目,你可以按如下寫你的循環:

list<Object> myList; 

BOOST_FOREACH(Object o, myList) 
    o.foo(); 
5

的Visual C++「爲每個」是不是標準C++,這意味着你將無法編譯其他編譯器,如您的代碼克++。然而,STL建議std::for_each,但其語法不太直觀。下面是其原型:

template <class InputIterator, class UnaryFunction> 
UnaryFunction for_each(InputIterator first, InputIterator last, UnaryFunction f); 

它需要兩個迭代限定的有效範圍,和f,以在此範圍內的每個對象適用的一元函數(或仿函數)。 可以使用的std :: for_each的這樣重寫你的榜樣:

void foo(Object o) 
{ 
    o.foo(); 
} 
... 
list<Object> myList; 

std::for_each(myList.begin(), myList.end(), foo); 

但是,如果你想貼近的各構建經典的語法,如果你確定如何使用升壓,你可以使用BOOST.FOREACH,這將讓你寫

list<Object> myList; 

BOOST_FOREACH(Object o, myList) 
{ 
    o.foo(); 
} 
+2

注意:對於每個(a中的b),即使在VS 2005/2008中,似乎也只是CLR - 只有在針對.NET時,才能在本機代碼中使用它,從而使每個「甚至不太便攜」。 否則我認爲你的答案非常好。 – Suma 2008-10-13 14:23:30

+0

另外請注意,如果你使用VS2010,你有lambda和std :: for_each()突然變得容易閱讀。 – Luis 2013-10-18 21:05:40

-1

我投票的呂克,

堅持到標準STL算法,你將是好得多。 STL算法可以使你的生活變得非常簡單,高效和安全。在看看離貨架算法,比如find_if,計數,count_if,排序,轉換等..

5點起...... http://www.sgi.com/tech/stl/table_of_contents.html

升壓很酷,但如果你要僅將它用於FOR_EACH宏,對於開發/構建環境設置來說太麻煩了。

當標準C++/stl無法以'簡單'方式解決問題時使用boost。

0

我也推薦BOOST_FOREACH。我通常創建的線沿線的宏:

#define _foreach(x,y) BOOST_FOREACH(x,y) 

這往往會增加可讀性。儘管如此,你必須小心與其他foreach實現的衝突。例如,Qt提供了一個'foreach',還有std :: for_each。

我發現std :: for_each實際上並沒有節省很多時間,因爲你最終需要大量的一次性函數對象來提供給for_each調用。通常使用STL迭代器製作標準的for-loop速度一樣快。

30

我不會使用它。雖然這是一個誘人的功能,語法是與即將推出的C++ 0x標準,它使用不兼容:

list<Object> myList; 

for (Object o : myList) 
{ 
    o.foo(); 
} 

做同樣的事情。

6

如果您想使用的foreach,並在同一時間,你不想增加額外的依賴(如升壓) - 此宏將幫助您:

#define VAR(V,init) __typeof(init) V=(init) 
#define FOREACH(I,C) for(VAR(I,(C).begin());I!=(C).end();I++) 

std::vector<int> numbers; 

FOREACH(I, numbers) 
{ 
    std::cout << *I << std::endl; 
} 
1

你的代碼確實不便攜。

以下工作與C++ 0x標準和Visual C++ 2010(它不支持新的「ranged for」語法,據我所知)。

#define for_each(_ITER_, _COLL_) for (auto _ITER_ = _COLL_.begin(); \ 
    _ITER_ != _COLL_.end(); _ITER_++) 

現在你可以這樣寫:

list<Object> myList; 

for_each (o, myList) 
{ 
    o.foo(); 
} 

http://www.boost.org/doc/libs/1_48_0/boost/foreach.hpp比較這對BOOST_FOREACH宏代碼這不僅是複雜的,也有一些其他Boost庫的依賴關係。