how could I bind random iterator to functor by std::tr1::bind?

I saw some functor would define

"typedef void result_type"

what is this for?

Besides, how could I bind random iterator to functor by std::tr1::bind?

Thank you very much
Last edited on
compiler gcc4.5 minGW
OS : windows xp sp3

I try something like this
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
template<typename T, typename errType>
class fastRowSum
{

  public :
    fastRowSum();
    typedef void result_type; //what is this line for?
    template<typename inputItr, typename outputItr>
    void operator() (T const VALUE, inputItr ref, outputItr out)
    {     
      error = VALUE > *ref ? VALUE - *ref : *ref - VALUE;
      errorSum += error;    
      *out = errorSum;
      ++ref; ++out;
    }

  private :
    errType error;
    errType errorSum;
};

template<typename T, typename errType>
fastRowSum<T, errType>::fastRowSum()
:error(0),
 errorSum(0)
 {}


1
2
//I call the functor like this
std::for_each(augBase.begin(), augBase.end(), std::tr1::bind(fastRowSum<T, U>(), std::tr1::placeholders::_1, augRef.begin(), matchingCost_Itr ) );


after the experiment, I found out that maybe bind didn't really pass the address of
augRef.begin() and matchingCost_Itr to the functor
That is why only the first value of the container would change
++ref; ++out; didn't increment the address of the iterator

Are there anyway to solve this?Thank you very much
Last edited on
The typedef is part of the interface to unary/binary/n-ary function objects. It specifies the return type of the function object. In many cases, you don't care about the return type -- it may be void. In other cases the compiler can figure it out. In a few cases, the compiler can't figure it out so it needs the typedef.

You have a problem of state. The function objects passed to the algorithms (std::for_each being one) cannot have state, at least not internally. To do what you want to do, I'd do this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
template< typename InputIter, OutputIter, typename ErrType, typename T >
struct fast_row_sum
{
    typedef void result_type;

    fast_row_sum( InputIter& ref, OutputIter& out, ErrType& errorSum ) :
        ref( ref ), out( out ), errorSum( errorSum )
    { errorSum = ErrType(); }

    result_type operator()( const T& value ) const
    {
        errorSum += abs( value - *ref );
        std::cout << "base = " << value << ", ref = " << *ref << ", out = " << *out << std::endl;
        ++ref;
        ++out;  
    }

  private:
    InputIter&   ref;
    OutputIter& out;
    ErrType&      errorSum;
};


int errorSum;
my_out_iter out_iter; // initialize to whatever
my_in_iter in_iter;  // initialize to whatever
fast_row_sum< my_in_iter, my_out_iter, int, int > adder( in_iter, out_iter, errorSum );
std::for_each( augBase.begin(), augBase.end(), std::tr1::bind( adder, std::tr1::placeholders::_1 ) );
// inspect errorSum directly for the total error 

Thanks, you are awesome
But I have to change the state of "out" from the "outside" too
I rewrite my functor at the second post, the previous one is not the original behavior I want
It is just a debug version

ps : I didn't use std::abs because I may handle unsigned value
Last edited on
Then you might want to make "out" public instead of private, or else have the "outside" modify out_iter directly.

I chose std::abs because you can always specialize the template if you want. It may already be specialized for unsigned values to do nothing. The advantage to this is if T and OutputIter::value_type are user-defined types, the user will have to overload operator- already, so they can just overload abs as well.
Thanks, I would give it a try
Topic archived. No new replies allowed.