2012-06-07 2 views
1

Я пытаюсь сохранить обратный вызов в классе. В настоящее время я делаю что-то вроде этого:Общий обратный вызов

struct Callback { 
    Callback (std::function<void()> func) : func_ (func){} 
    void call() const { func(); } 

private: 
    std::function<void()> func_; 
}; 

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

Есть ли способ использовать такой класс, как этот, где я передаю его, как его назвать?

void increment (int &n) { 
    ++n; 
} 

int main() { 
    int someNum = 5; 
    Callback callback (increment, someNum); //will call `increment (someNum);` 
} 

Я думал использовать параметр обновления для хранения аргументов, и в typename для хранения возвращаемого типа, а затем, сделав std::function<ReturnType (Args)> callback_ рода вещи, и называя это что-то вроде callback_ (givenArgs...);. Однако я недостаточно разбираюсь в шаблонах, чтобы сделать это, или даже выяснить, возможно ли это.

Реальное использование Я бы выбрался из этого (по крайней мере прямо сейчас) для таймера, но, возможно, сделать небольшой класс generic_function<>, который обертывает std::function<>, поможет больше. Для этого примера, хотя, таймер, который делает паузу и продолжает воспроизведение через каждые 2 секунды:

void togglePause (Countdown &c) { 
    c.togglePause(); 
} 

int main() { 
    Countdown main (10000); //create countdown of 10s 
    Countdown delay (2000, togglePause, main); //this one calls func when expired 

    for (; !main.expired();) { //go while unpaused time < 10s 
     delay.wait().reset(); //wait 2s, call callback, reset back to 2s 
    } 
} 

Конечно, это может быть применен к другим понятиям, как хорошо, но я не уверен, как идти о достижении этого синтаксиса в первое место. Я могу построить две разные формы в случае, если тип возврата void просто отлично от несвязанного предыдущего вопроса, но хранение функции с любым числом и типами аргументов меня смущает. Если это возможно, как я могу использовать синтаксис, как это? Если нет, насколько близок синтаксис?

+1

Я был по этой дороге, хотя не с C++ 11 (что должно сделать это намного проще, на самом деле). Следите за [соглашениями о невидимом вызове] (http://stackoverflow.com/q/9729438/21475). – Cameron

+0

@Cameron, Спасибо за хедз-ап. Я должен буду следить за этим, так как я, без сомнения, попробую это с помощью функции winapi по дороге и смущен. – chris

+0

Что такое ваша платформа? (MSVC++? GCC? X86 или x64?) – Cameron

ответ

5

Я думаю, что вы просто хотите использовать зЬй :: BIND для преобразования функции с аргументом в функцию не принимает никаких аргументов:

int main() { 
    int someNum = 5; 
    std::function<void (void)> boundFunc = std::bind(increment, std::ref(someNum)); 
    Callback callback (boundFunc); //will call `increment (someNum);` 
} 

Обратите внимание, что вам нужно БППП :: реф, чтобы гарантировать, что someNum является переданы по ссылке и что вам нужно убедиться, что someNum остается в области дольше, чем обратный вызов.

+0

Похоже, он должен работать (хорошее мышление), но, к сожалению, этого не происходит. Возможно, это я. См. Мой обновленный вопрос. – chris

+0

Я только что обновил это с помощью необходимого std :: ref –

+0

Да, я стонал довольно громко, когда увидел это. Он отлично работает с тестовым примером, поэтому я могу предположить, что это произойдет, когда я его реализую. Большое спасибо. Это намного проще, чем то, что я имел в виду. Мне всегда удается найти самый утомительный способ сделать что-то. – chris

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