Question

I want to pass a struct implementing operator() in to a function that accepts boost::function. This struct keeps track of the number of times it's been called.

struct CallCounter
{
    CallCounter() : count( 0 ) {}
    void operator()()
    {
        // do stuff
        cout << "count is at " << count << endl;
        ++count;
    }

    int count;
};

However, when I try to access count after passing it to another function, count is still at 0.

void callNTimes( int n, boost::function<void()> func )
{
    for ( int i = 0; i < n; ++i )
        func();
}

int main()
{
    CallCounter counter;
    callNTimes( 20, counter );

    cout << counter.count << endl; // prints 0
    return 0;
}

Even though while counter is being called, it's printing out the correct count. I understand that boost::function is making a copy of my struct counter. Is there a way to pass it by reference so that afterwards, count is the right number?

Was it helpful?

Solution

The boost function stuff takes variables by value by default, much like normal functions. If you want the function to use a reference to your CallCounter, you have to tell it that explicitly:

callNTimes( 20, boost::ref(counter) );

See it here: http://coliru.stacked-crooked.com/a/5843b6dde685b569

There also exists a boost::cref if you want a constant reference, but no boost::rref (which would be nearly identical to a value, but single use. function is multi-use, so no moves). Additionally, as of C++11, all of this is also in the std namespace.

In addition, Jefffrey's suggestion is generally considered a better way to code this sort of thing, if possible. It can have a negative impact on compile times though.

OTHER TIPS

I see that you are using boost::function. It's actually not necessary here, you can just use templates and pass the functor by reference:

template<typename Functor>
void callNTimes( int n, Functor& func )
{
    for ( int i = 0; i < n; ++i )
        func();
}

Live demo

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top