如何定义采用最通用数量和参数类型的函数

时间:2018-10-17 08:24:56

标签: c++

如何重新定义此功能:

unsigned int uiTimer(int milliseconds, int (*f)(void *data), void *data)

,以便可以将此函数用作参数(或任何其他函数,而无需考虑签名)?

int filterInput(uiEditableCombobox *pBox, void *pvData)

像这样:

uiTimer(1000, filterInput, NULL);

我尝试将filterInput包裹在“ timerDone(void *)”中,但是无法完成,因为我需要将参数传递给filterInput。

int timerDone(void *) {
    filterInput();  // <--- I need context to be passed as params
}
uiTimer(1000, timerDone, NULL);

2 个答案:

答案 0 :(得分:2)

更改签名以使用std::function

#include <functional>
unsigned int uiTimer(int milliseconds, std::function<int(void*)> f, void *data)

使用lambda expressions传递参数:

uiEditableCombobox *box;
uiTimer(1000, [=](void* data) { return filterInput(box, data); }, nullptr);

答案 1 :(得分:2)

您可以通过以下方式将任何函数指针用作参数:

template<typename R, typename... Ts>
void f(R(*functionPointer)(Ts...))
{ /* ... */ }

不幸的是,成员函数指针必须使用单独的大小写:

template<typename R, typename T, typename... Ts>
void f(R(T::*functionPointer)(Ts...))
{ /* ... */ }

但是从本质上讲,任何函数指针也将被单个模板参数捕获,因为它也是有效的类型,但是您必须意识到您允许传递更多的实体(例如,不是函数指针)。 / p>

template<typename T>
void f(T&& f)
{ /* ... */ }

这是一个工作示例,展示了在模板函数中使用函数指针的多种方式:http://coliru.stacked-crooked.com/a/a1a01993266e6351