2014-04-17 1 views
0

Я хочу передать структуру, реализующую operator(), функции, которая принимает boost::function. Эта структура отслеживает количество раз, когда она была вызвана.Сделать boost :: function получить ссылку на мой объект функции

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

    int count; 
}; 

Однако, когда я пытаюсь получить доступ count после передачи его в другую функцию, count еще в 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; 
} 

Несмотря на то, в то время как counter вызывается, это распечатывания правильный count. Я понимаю, что boost::function делает копию моего struct counter. Есть ли способ передать его по ссылке, чтобы впоследствии count был правильным номером?

+0

Я не читал вопрос достаточно подробно :( –

+0

@MooingDuck, вы должны разместить его в качестве ответа. Вместо этого я предпочитаю шаблон.;) – Shoe

ответ

3

Буст function материал принимает переменные значения по умолчанию, так же, как обычные функции. Если вы хотите, чтобы функция использовать ссылки ваших CallCounter, вы должны сказать ей, что в явном виде:

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

Посмотрите здесь: http://coliru.stacked-crooked.com/a/5843b6dde685b569

Там также существует boost::cref, если вы хотите постоянную ссылку , но не boost::rref (что было бы почти идентично значению, но одноразовое использование. function является многоцелевым, поэтому никаких ходов). Кроме того, с C++ 11 все это также находится в пространстве имен std.

Кроме того, предложение Джефффри обычно считается лучшим способом кодирования такого рода вещей, если это возможно. Это может оказать негативное влияние на время компиляции.

1

Я вижу, что вы используете boost::function. Это на самом деле здесь нет необходимости, вы можете просто использовать шаблоны и передать функтор по ссылке:

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

Live demo

+0

Я думаю, что рекомендую «Functor &&» в C++ 11 или 'const Functor &'/'Functor &' пара в C++ 03. –

+1

В этом конкретном случае между 'const Functor &' и 'Functor &' будет работать только последний, а 'Functor &&' не сильно изменится; но, как общая идея, я, безусловно, второе предложение. – Shoe

Смежные вопросы