2011-12-21 16 views
0

std::copyと同様の機能をstd::remove_ifとして使用しているとします。フックを追加するにはどうすればいいですか?特に私はコピーのステータスを記録したいと思う。std :: copy hooks

for(from begin to end iterator) 
{ 
    do the copy of the container; 
    cout << "." << flush; 
} 

が、唯一の方法はかなりありますstd::copy

+0

を、私は質問を理解していませんでした。 'copy_if'のようなものが欲しいですか? – Nawaz

+3

私はかなり彼が以下の答えで与えられたようなものであることを確信しています:コピーループの各繰り返しで特定の関数を呼び出すこと。これは疑似コードによって明確にされた意図です。 – stijn

答えて

3

を使用して::終わりに私はと等価で何かしたいビューのコピーの視点からまったく同じように動作し、独自のイテレータと出力イテレータをラップしますが、 internalyyはフックアクションも行います。 例えば、これは、いくつかの演算子の実装が考えられます。あなたのコンパイラは、STDを持っていない場合は、コンストラクタで

template< class T, bool constcv > 
class HookingIterator : public std::iterator< std::forward_iterator_tag, .... > 
{ 
public: 
    reference operator*() 
    { 
    dereference_hook(); 
    return *actual_iterator_member; 
    } 

    this_type& operator ++() 
    { 
    increment_hook(); 
    ++actual_iterator_member; 
    return *this; 
    } 
}; 

は、実際のイテレータを供給し、とstd ::関数オブジェクト(またはプレーン機能/いくつかのインターフェイスインスタンス::関数)。

1

次の例のように、あなたはあなたのフックに入れた構造、にイテレータをラップすることができます:

#include<list> 
#include<algorithm> 
#include<numeric> 
#include <iostream> 
#include <vector> 
#include <assert.h> 
using namespace std; 

template<typename T> 
struct wrap_{ 

    T i; 

    typedef typename T::value_type value_type; 
    typedef typename T::difference_type difference_type; 
    typedef typename T::iterator_category iterator_category; 
    typedef typename T::pointer pointer; 
    typedef typename T::reference reference; 

    wrap_(T i) : i(i){} 
    wrap_& operator++(){ 
     cout << "++" << endl; 
     i++; 
     return *this; 
    } 
    wrap_ operator++(int){ i++; return *this; } 

    difference_type operator-(wrap_ j){ 
     return i-j.i; 
    } 

    value_type& operator*(){ 
     cout << "*" << endl;  
     return *i; 
    } 

}; 

template<typename T> 
wrap_<T> wrap(T i){ 
    return wrap_<T>(i); 
} 

int main(){ 
    vector<int> V(5); 
    for (int i=0;i<V.size();i++) V[i]=i+1; 

    list<int> L(V.size()); 
    copy(wrap(V.begin()), wrap(V.end()), L.begin()); 
    assert(equal(V.begin(), V.end(), L.begin())); 
} 

出力:

* 
++ 
* 
++ 
* 
++ 
* 
++ 
* 
++ 
+0

ありがとうございます。このようなクラスがいくつかの図書館に用意されていますか? –

+0

残念ながら、私は知らない。 – Vlad