3

関数の引数として任意のコンテナーを渡し、それを反復処理したいと思います (要素を消去したりプッシュしたりしません)。残念ながら、これを行う標準的な方法はないようです。

私の頭に浮かぶ最初の解決策は、CollectionInterfaceSTLコンテナをラップするクラスによって実装されるインターフェース(と呼びましょう)です。したがって、関数宣言は次のようになります。

f(const CollectionInterface * collection);

または、コンパイル時にバインドし続けるという利点があるメソッド テンプレートについて考えていました。

template <class CONTAINER> void f(const CONTAINER & collection);

どちらの方法が良いと思いますか?

4

3 に答える 3

7

フォワードイテレータ? これは、マルチパス アルゴリズムも使用できるInputIterator (または OutputIterator) のタイプです (インクリメントしても以前の値は無効になりません)。

イテレーター (Java イテレーターとはまったく異なります) は、C++ コレクションを統合する中心的なスレッドです。それらで動作するアルゴリズムの例 (および関連する反復子の型の要件) については、 から始めることができます<algorithm>。特に、searchは ForwardIterator の使用例を提供します。[first1, last1]rangeで定義されたシーケンスの範囲内で最初に出現するものを見つけます[first2, last2)。これらはすべて、 の要件を満たすオブジェクトですForwardIterator

于 2010-06-21T23:52:18.993 に答える
4

関数の引数として任意のコンテナーを渡し、それを反復処理したいと思います(要素の消去やプッシュは行いません)。

イテレータを渡します。実装と使用の例を次に示します。

template <typename Iter>
void function(Iter begin, Iter end)
{
    for (Iter it = begin; it != end; ++it)
    {
        std::cout << *it << std::endl;
    }
}

int main()
{
    std::string array[] = {"hello", "array", "world"};
    function(array, array + 3);

    std::vector<std::string> vec = {"hello", "vector", "world"};
    function(vec.begin(), vec.end());
}

多くの場合、実際に関数を作成する必要はありませんが、代わりにライブラリ機能を使用して関数を作成し、それを適用するだけでよいことに注意してくださいstd::for_eachstd::accumulateまたは、またはのような既存のアルゴリズムを使用することをお勧めしますstd::find_if

于 2010-06-22T00:45:39.523 に答える
4

処理したい場合は、参照ではなくコンテナ全体を受け入れるメソッドを作成することもできます。標準ライブラリ コンテナーへの反復子はすべて、メンバー関数begin()およびを介して提供されます。end()場合によってはrbegin()rend()逆方向に反復するために提供されます。テンプレートが機能する方法では、オブジェクトの派生元である実際のインターフェイス タイプを作成する必要はありません。代わりに、要件は使用されるオブジェクトによって推測されます。

template<typename Container> void Function(const Container& c) {
    for(typename Container::const_iterator i = c.begin(), end = c.end(); i != end; ++i)
       //do something
}

イテレータを渡すと、関数を使用する際の柔軟性が向上します。特に、すべてのイテレータが明示的な関数begin()end()関数を持つコンテナーから取得されるわけではなく、必要な明示的な部分範囲を指定できます。しかし、この方法が適切な場合もあります。

于 2010-06-22T00:33:12.713 に答える