Odpowiedź dribeas jest poprawna w odniesieniu do współczesnego C++.
W trosce o interes, istnieje również proste rozwiązanie lo-tech ze świata C, które w miarę możliwości działa w C++. Zamiast zezwalać na dowolne parametry, zdefiniuj funkcję jako void (*func)(void*)
i wykonaj "parametry" void*
. Wówczas zadaniem rozmówcy jest zdefiniowanie struktury, która będzie zawierać parametry i zarządzanie cyklem życia. Zwykle rozmówca również napisać prosty wrapper do funkcji, która jest naprawdę potrzebne, aby być nazywany:
void myfunc(int, float); // defined elsewhere
typedef struct {
int foo;
float bar;
} myfunc_params;
void myfunc_wrapper(void *p) {
myfunc_params *params = (myfunc_params *)p;
myfunc(params->foo, params->bar);
}
int main() {
myfunc_params x = {1, 2};
AddTimer(23, 5, myfunc_wrapper, &x);
sleep(23*5 + 1);
}
W praktyce chcesz „ognia i zapomnij” liczniki, więc jeśli używasz tego systemu może być konieczne sposób dla timera udaje się uwolnić wskaźnik userdata po zakończeniu wszystkich wypalania.
Oczywiście ma to ograniczone bezpieczeństwo typu. Zasadniczo nie powinno to mieć znaczenia, ponieważ ktokolwiek dostarcza wskaźnik funkcji i wskaźnik danych użytkownika, nie powinien mieć dużej trudności z zapewnieniem ich zgodności. W praktyce ludzie znajdują sposoby na pisanie błędów i sposoby na obwinianie cię, ponieważ ich kompilator nie powiedział im o błędach ;-)
będzie wywoływał wówczas tylko funkcje nieważne? – Ninja
@Ninja Tak, oczywiście. Jako dzwoniący, jeśli nie wiesz nawet, jaki jest typ zwrotu, w jaki sposób możesz użyć tej funkcji? Możesz użyć 'boost :: function' i przesłać typ zwrotu do tego, co chcesz. Jeśli chcesz nowoczesną alternatywę C++, możesz użyć 'boost :: function ', aby grać z pewnym typem wymazania. –
kizzx2