1

私は多態的なインターフェースを持っています

struct Interface {
  Interface(SomeType& other)
  : range([=](){ return other.my_range(); }), /*...*/ {}
  Interface(SomeOtherType& other)
  : range([=](){ return other.some_range(); }), /*...*/ {}

  const std::function<Range(void)> range;
  /// ...
};

両方の範囲の要素は同じ型 (例: ) ですが、 byと by によってint返される型は異なります。たとえば、一方が aで、もう一方が aです。インターフェイスには、単一のタイプが必要です。my_range()some_range()filtered counting rangetransformed filtered counting rangeRange

使用してみましboost::any_rangeたが、パフォーマンスが大幅に低下します。vector範囲要素を a にコピーして、代わりにベクトルを返す必要は避けたいと思います。

any_rangeコピーの代替手段はありますか?

4

2 に答える 2

1

ちょっと、しかしそうではありません。

データがどのように格納されているかわからない場合に、データに順次アクセスしたい。次の 3 つのオプションがあります。

  • データを既知の形式のコンテナーにコピーします ("return vector" オプション)。
  • コンパイル時のポリモーフィズムを使用して、正しいアクセス方法を選択します (インターフェイスを使用しているため、std アルゴリズムが行う方法ではありません)。
  • ランタイム ポリモーフィズムを使用して、正しいアクセス方法を選択してください。

したがって、インターフェイスを使用するという制約により、2 番目の方法は使用できません。1 つ目と 3 つ目はどちらもオーバーヘッドが発生します。

3 番目のことを行う明白な方法は、 ですany_range。しかし、やりたいことによっては、それが唯一の方法ではありません。問題any_rangeは、単純な for-each ループでは、すべての要素に対して 3 つの仮想呼び出し (インクリメント、比較、逆参照) があることです。

やりたいことが単純な for-each 反復である限り、インターフェイス レベルでループを実装することにより、オーバーヘッドを 1 つの仮想呼び出しに減らすことができます。

struct Interface {
    Interface(SomeType& other)
    : traverse([=](std::function<void(int)> body) {
      for (int i : other.my_range()) body(i);
    }) {}

    const std::function<void (std::function<void(int)>)> traverse;
};

もちろん、範囲の使用方法が非常に限られている場合にのみ機能します。

于 2013-07-02T17:56:59.090 に答える