次の (単純化された) シナリオを検討してください。
class edgeOne {
private:
...
public:
int startNode();
int endNode();
};
class containerOne {
private:
std::vector<edgeOne> _edges;
public:
std::vector<edgeOne>::const_iterator edgesBegin(){
return _edges.begin();
};
std::vector<edgeOne>::const_iterator edgesEnd(){
return _edges.end();
};
};
class edgeTwo {
private:
...
public:
int startNode();
int endNode();
};
class containerTwo {
private:
std::vector<edgeTwo> _edges;
public:
std::vector<edgeTwo>::const_iterator edgesBegin(){
return _edges.begin();
};
std::vector<edgeTwo>::const_iterator edgesEnd(){
return _edges.end();
};
};
つまり、2 つのほぼ同一のエッジ タイプと 2 つのほぼ同一のコンテナ タイプがあります。各種類を個別に反復できます。これまでのところ、とても順調です。
しかし、私のユースケースは次のとおりです。いくつかの基準に基づいて、containerOne または containerTwo オブジェクトを取得します。エッジを反復処理する必要があります。しかし、タイプが異なるため、コードの複製なしでは簡単に行うことはできません。
std::vector<edgeOne>::const_iterator
したがって、私の考えは次のとおりです。次のプロパティを持つイテレータstd::vector<edgeTwo>::const_iterator
が必要です。-const edgeOne &
またはを返す代わりにconst edgeTwo &
、operator*
を返す必要がstd::pair<int,int>
あります。つまり、変換を適用します。
特にBoost.Iterator Libraryを見つけました:
- iterator_facade は、標準に準拠したイテレータを構築するのに役立ちます。
edgeOne
transform_iterator は、 transformおよびedgeTwo
toに使用できますがstd::pair<int,int>
、完全なソリューションがどのように見えるかは完全にはわかりません。イテレータのほぼ全体を自分で作成した場合、transform_iterator を使用する利点はありますか?それとも、ソリューションがより重くなるだけでしょうか?
イテレータは次のデータのみを保存する必要があると思います:
- 値のタイプが edgeOne か edgeTwo かを示すフラグ (現時点では bool で十分ですが、必要に応じて enum 値の方が簡単に拡張できます)。
- 両方のイテレータ タイプのエントリを持つ
union
(フラグに一致するものだけがアクセスされる)。
それ以外は、オンザフライで計算できます。
このポリモーフィック動作に対する既存の解決策、つまり同じ値型を持つ 2 つ (またはそれ以上) の基になるイテレータ実装を組み合わせたイテレータ実装があるのではないかと思います。そのようなものが存在する場合、それを使用して 2 つの を組み合わせることができますtransform_iterator
。
ディスパッチ (つまり、containerOne または containerTwo オブジェクトにアクセスする必要があるかどうかの決定) は、独立した関数によって簡単に実行できます ...
この問題に関するご意見やご提案はありますか?