0

假设我正在使用std::copy类似的功能std::remove_if,......添加钩子的最佳方法是什么?特别是我想记录复制的状态。最后我想要的东西相当于:

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

但使用std::copy

4

2 回答 2

3

几乎只有一种方法:用您自己的迭代器包装输出迭代器,从副本的角度来看,它的行为完全相同,但 internalyy 也执行钩子操作。例如,这可能是一些运营商的实现:

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::function 对象(或者,如果您的编译器没有 std::function,则提供普通函数/一些接口实例)。

于 2011-12-21T08:24:42.727 回答
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())); 
}

输出:

*
++
*
++
*
++
*
++
*
++
于 2011-12-21T08:29:28.463 回答