2009-06-09 9 views
4

リストを反復処理するBOOST_FOREACHループがあります。残念ながら、イテレータを特定のアイテムにキャッシュする必要もあります。 BOOST_FOREACHループのイテレータにアクセスする

typedef List::iterator savedIterator; 

BOOST_FOREACH(Item &item, list) 
{ 
// stuff... 
    if (condition) 
    savedIterator = &item; // this won't work 

// do more stuff...  
} 

はもちろん、私は、forループlist.beginを()... list.end()を使用してこれを行うことができますが、私はBOOST_FOREACHを好きに成長してきました。これには道がありますか?

答えて

7

ループ内の現在のアイテムを指すイテレータにアクセスできないため、これは不可能です。

現在のアイテムデータを使用してリストからイテレータをフェッチすることはできますが、それはパフォーマンスにも優れているかどうかわかりません。

私はlist.begin().. list.end()で既に提案したソリューションを使用することをお勧めします。これは私の意見では実装と認識が最も簡単です。

4

Boost.Foreachでは、逆参照されたイテレータへの参照は、Boost.Foreachが設計したものであるため、かなり参考になっています。範囲内の要素へのアクセスを簡素化します。しかし、あなたはちょうどあなたがstd::find_if()をしようとする場合があります基準を満たす単一の要素を探している場合:

struct criteria { 
    template <class T> 
    bool operator()(T const & element) const { 
    return (element /* apply criteria... */)? true : false; 
    } 
}; 

// somewhere else 
List::iterator savedIterator = 
    std::find_if(list.begin(), list.end(), criteria()); 

あなたはリスト全体に対して操作を適用するようにまた見える - 私はその場合には、 std::min_element()またはstd::max_element()と、boost::transform_iteratorのようなBoost.Iteratorsのようなものを使用することをお勧めします。

struct transformation { 
    typedef int result_type; 
    template <class T> 
    int operator()(T const & element) const { 
    // stuff 
    int result = 1; 
    if (condition) result = 0; 
    // more stuff 
    return result; 
    } 
}; 

// somewhere else 
List::iterator savedIterator = 
    std::min_element(
    boost::make_transform_iterator(list.begin(), transformation()), 
    boost::make_transform_iterator(list.end(), transformation()), 
).base(); 
+2

Upvoted、それは私が時々C++を憎むどれだけ私を思い出させるだけの理由。 – Roddy

1

の人がこれをしないのはなぜな種類の不思議:

#define foreach(iter_type, iter, collection) \ 
for (iter_type iter = collection.begin(); iter != collection.end(); ++iter) 
+1

'collection'が副作用のある式ならどうなりますか?マクロはそれを2回評価します。また、伝統的なforeachの全体的なポイントは、イテレータ(およびその長い扱いにくい型名)をまったく使わずに直接値を取得することです。 –

+0

コレクションが表現であれば良い点です。その場合、式を評価し、それを参照としてforeachに渡します。 collection_type&c = foreach(iter_type、it、c)... イテレータにアクセスできるという利点は、柔軟性のためです(この記事の質問など)。私はそれが支払う価格の多くではないと思う。多分それは私の特定のスタイルです... –

+0

'BOOST_FOREACH'はあなたが考えるように簡単ではありません。それらの記事をお読みください。 たとえば、 'collection'はイテレータを持たない配列です。 http://cplusplus.bordoon.com/boost_foreach_techniques.html http://www.artima.com/cppsource/foreach.html(BOOST_FOREACHの作者がこの記事を書いています) –

関連する問題