2

私は次のマクロを持っています:

#define FOREACH(decl, c) BOOST_FOREACH(decl, std::make_pair((c).begin(), (c).end()))

(私のコンテナーは可変反復APIを実装していないため、このマクロを使用しています。)

それに関する問題は、それcが2回評価されることです。

私の質問は、このマクロを次のように修正できるかどうかです。

  1. c最大で1回評価されます
  2. 最初の条件を満たすために作成されたローカル変数は、それぞれのforeachスコープ内にのみ存在します。
4

3 に答える 3

8

インラインヘルパー関数を使用できます。

#define FOREACH(decl, c) BOOST_FOREACH(decl, pair_helper(c))

template <typename T>
inline std::pair<typename T::iterator, typename T::iterator> pair_helper (T c) {
    return std::make_pair(c.begin(), c.end());
}
于 2012-01-14T00:05:23.750 に答える
6

このハッカリーは必要ありません。Boost.Foreachは、イテレータを取得するためにBoost.Rangeに依存しています。これを拡張する方法は2つあります。

  1. メンバー関数とネストされたタイプを提供します:http ://www.boost.org/doc/libs/1_48_0/libs/range/doc/html/range/reference/extending/method_1.html
  2. 独立した関数を提供し、メタ関数を特殊化します:http ://www.boost.org/doc/libs/1_48_0/libs/range/doc/html/range/reference/extending/method_2.html

begin()今あなたの場合、あなたはとメンバー関数を提供しているように見えますがend()、ネストされた型を提供していませんiterator(私はあなたが可変反復APIによって意味するものだと思います)。あなたは2つのことのうちの1つをすることができます。

typedefまず、次のようにネストされたイテレータタイプを使用できます。

typedef const_iterator iterator;

次に、クラスを変更できない場合は、次のようにメタ関数を特殊化できます(YourContainerをコンテナータイプに置き換えます)。

namespace boost
{
    //
    // Specialize metafunctions. We must include the range.hpp header.
    // We must open the 'boost' namespace.
    //

    template< >
    struct range_mutable_iterator< YourContainer >
    {
        typedef YourContainer::const_iterator type;
    };

    template< >
    struct range_const_iterator< YourContainer >
    {
        typedef YourContainer::const_iterator type;
    };

} // namespace 'boost'

もちろんconst_iterator typedef、クラスに'dがあると仮定します(可変をサポートしていないと言ったので)。そうでない場合は、YourContainer::const_iterator自分のタイプに置き換える必要がありますconst_iterator

于 2012-01-14T02:30:58.260 に答える
2

「ステートメント式」は、マクロ引数の繰り返し評価を回避するためのgcc /g++拡張機能です。

#define make_pair_of_iterators(c) ({typeof(c)& c_ = (c); make_pair(c_.begin(), c_.end()); })

次に、次のことができます。

#define FOREACH(decl, c) BOOST_FOREACH(decl, make_pair_of_iterators(c) )

(そしてtypeof、gcc / g ++拡張機能でもあります。)

于 2012-01-14T00:02:50.923 に答える