0

私は STL イテレータの現在の制限について熟考しており、それを回避するエレガントな方法があるかどうか疑問に思っています。これが私の状況です: シーケンス コンテナーをカプセル化するクラスと、コンテナーの内容を変更するジェネリック メソッドがあります。次に例を示します。

class Container {
  typedef std::vector<int> Data;
  Data data_;
 public:
  template <class Mutator>
  ?? mutate() {
    Mutator m;
    return m(??);
  }
};

簡潔にするためにいくつかの詳細は省略されていますが、私が検討している主な問題は、ミューテーター ( m() ファンクター呼び出しの ?? ) に何を渡すかです。二次的な問題は、ミューテーターの単純な構成を可能にするために mutate から何を返すかです。1 つの可能性は、イテレータの begin/end ペアを data_、または boost::sub_range に渡す (そして返す) ことです。次に例を示します。

template <class Mutator>
boost::sub_range<Data> mutate() {
  Mutator m;
  return m(boost::sub_range<Data>(data_);
}

これにより、範囲内のすべての値を否定したり、係数を掛けたりするなど、データに対して必要なことのほとんどを行うことができます。これにより、この (短縮された) バージョンのように、さまざまなミューテーターを連鎖または構成することもできます。

return m1(m2(m3(data_)));

したがって、任意のミューテーターは、たとえば、その入力のサブ範囲を選択して、外側のミューテーターが機能する範囲を制限することができます。これは望ましい機能です。そして、これらすべてのミューテーターはデータをその場で変更できるため、非常に効率的です。

ただし、この構文でできないことは、コンテナーのサイズを変更することです (少なくともベクターでは変更できません)。そのため、要素を挿入または削除するミューテーターは、反復子ベースのインターフェイスでは機能しません。代替インターフェースは、コンテナー全体をミューテーターに渡します。その場合のサブレンジングの処理方法がわかりません。また、一般的で最小限の要件の反復子ベースのソリューションよりも洗練されていないソリューションのようにも感じます。

この制限に対処する方法についてのアイデアをいただければ幸いです。

4

1 に答える 1

0

ファンクター (考える: 関数合成) をboost::bindと組み合わせることができます。

一方、私は完全には理解していないと感じています.2番目のファンクターは最初のファンクターとは異なる範囲で動作するはずですか? データはコンテナーから削除されますか?

注意: 現在のソリューションには明らかなコストがかかります。「ミューテーター」のすべての構成には、「ミューテーターの実際の構成」ではなく、新しい反復が必要になります。

于 2010-06-20T22:09:33.117 に答える