2016-11-10 4 views
2

私は、(テンプレート化された)反復子のペアIterator begin1Iterator end1を持っています。私は関数fooを持っています。署名付きで適応イテレータを取得するための迅速かつ汚れた方法は何ですか?

template <typename ForwardIterator> 
void foo(ForwardIterator begin, ForwardIterator end); 

これはその範囲で何かします。今、私はfooが実際の範囲の要素ではなく、むしろいくつかのラムダまたはいくつかの関数barによってこれらの要素の変換に作用するようにしたいと思います。私はは、変換された値のためにstd :: transformを使用するか、それ以外の場合はテンポラリストレージを使用できません。これは、あまりにも多くの領域を占めるか、またはヒープ上に何かを割り当てることができないためです。

今、自分でイテレーターを適用することはできますが、私はむしろ既製のものを使用して、ホイールを再構成しません。

これで、私が欲しいことを行うためにfooに渡すことができる、適切な適応イテレータのペアを取得するための迅速かつ汚れた方法は何ですか?すなわち、私のため

foo(magic(begin), magic(end)) 

または

auto new_pair = magic(begin, end); 
foo(new_pair.first, new_pair.second); 

を呼び出すことができますか?

+0

最終的には標準になる@ eric-nieblerの[range-v3 library](https://github.com/ericniebler/range-v3)を試してみてください! –

+1

[ブーストイテレーターアダプター](http://www.boost.org/doc/libs/1_62_0/libs/iterator/doc/index.html)は別の方法です – Jarod42

+0

@BrianRodriguez:より具体的に/明示的にすることができますか?答えに? – einpoklum

答えて

2

Eric Nieblerのrange-v3ライブラリはこれに非常に優れたソリューションを提供し、将来の標準に含まれる予定です。ここに簡単な例があります:

std::vector<int> vi{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; 
using namespace ranges; 
auto rng = vi | view::transform([](int x){ return x % 2; }); 
foo(rng.begin(), rng.end()); // When foo dereferences these iterators, it 
           // will see: [1, 0, 1, 0, 1, 0, 1, 0, 1, 0]. 

これはすべて怠け者で効率的です。 :)

+1

!私は図書館について知っていましたが、時には彼のブログを読んだこともありますが、その構文は分かりませんでした。すごい。 'cat |のようなコマンドチェーンをシミュレートするのは難しくありません。 grep | grep | grepその文法で「カップ」を作ります。 –

関連する問題