23

for eachVisual C++ 2008 (およびおそらく以前のバージョンも?) が反復を容易にするために stl リストなどの構文をサポートしていることを最近発見したばかりです。例えば:

list<Object> myList;

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

私はそれを発見してとてもうれしく思いましたが、私のコードを gcc やその他のコンパイラでコンパイルできるようにする必要があると誰かが判断した恐ろしい日の移植性について心配しています。この構文は広くサポートされていますか? また、移植性の問題を気にせずに使用できますか?

4

9 に答える 9

33

私はそれを使用しません。これは魅力的な機能ですが、この構文は、次のものを使用する今後の C++0x 標準と互換性がありません。

list<Object> myList;

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

同じことをする。

于 2008-10-13T14:24:38.317 に答える
25

For each は、標準の C または C++ 構文ではありません。このコードを gcc または g++ でコンパイルできるようにする場合は、反復子を作成し、標準の for ループを使用する必要があります。

クォンタムピート

[編集] これは MS Visual C++ に導入された新機能のようです。そのため、これは移植性がありません。参照: http://msdn.microsoft.com/en-us/library/xey702bw%28VS.80%29.aspx [/編集]

于 2008-10-13T12:23:03.100 に答える
21

非常に優れた移植可能な代替手段があります: Boost.Foreach。このヘッダーをプロジェクトにダンプするだけで、ループを次のように記述できます。

list<Object> myList;

BOOST_FOREACH(Object o, myList)
    o.foo();
于 2008-10-13T12:31:05.843 に答える
6

foreach を使用したいと同時に、追加の依存関係 (Boost など) を追加したくない場合 - このマクロが役立ちます。

#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;
}
于 2008-10-13T15:11:03.463 に答える
5

Visual C++ の "for each" は標準の C++ ではありません。つまり、g++ などの他のコンパイラでコードをコンパイルすることはできません。ただし、STL はstd::for_eachを提案していますが、その構文は直感的ではありません。そのプロトタイプは次のとおりです。

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

有効な範囲を定義する 2 つの反復子を取り、単項関数 (またはファンクター) f をこの範囲内の各オブジェクトに適用します。次のように std::for_each を使用して例を書き直すことができます。

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

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

ただし、 for each コンストラクトの従来の構文に近づきたい場合、および Boost の使用に問題がない場合は、BOOST.FOREACHを使用できます。

list<Object> myList;

BOOST_FOREACH(Object o, myList)
{
    o.foo();
}
于 2008-10-13T12:36:44.227 に答える
2

Boost ライブラリには、移植可能なForEach 実装があります。

于 2008-10-13T12:29:44.117 に答える
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 マクロ コードと比較してください。これは複雑であるだけでなく、他のブースト ライブラリに多くの依存関係があります。

于 2012-01-03T15:33:17.200 に答える
0

BOOST_FOREACHもおすすめです。私は通常、次の行に沿ってマクロを作成します。

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

これにより、可読性が向上する傾向があります。ただし、他の foreach 実装との衝突には注意する必要があります。たとえば、Qt は「foreach」を提供し、std::for_each があります。

std::for_each は、for_each 呼び出しに提供する 1 回限りの関数オブジェクトを多数作成することになるため、実際にはあまり時間を節約できないことがわかりました。通常、STL イテレータを使用して標準の for ループを作成するのと同じくらい高速です。

于 2008-10-13T13:56:44.987 に答える
-1

私はリュックに一票

標準の STL アルゴリズムに固執すれば、はるかにうまくいくでしょう。STL アルゴリズムは、あなたの生活を非常に簡単、効率的、かつ安全にすることができます。find_if、count、count_if、sort、transform などの既製のアルゴリズムを見てみましょう...

ポイント5以降... http://www.sgi.com/tech/stl/table_of_contents.html

Boost はクールですが、FOR_EACH マクロだけに使用する場合、開発/ビルド環境のセットアップに関しては面倒です。

標準の c++ / stl では「簡単な」方法で問題を解決できない場合は、boost を使用します。

于 2008-10-13T13:39:27.017 に答える