标题可能有点令人困惑,所以我会更清楚地解释它。
我有一个类:
class foo
{
public:
foo(%Some function% *) { %Some function pointer% = %Some function%; }
%Some output% callFunction(%Some input%);
private:
%Some function pointer% bar;
}
最好,我希望能够在%Some function pointer%
中存储给定的功能,以便在整个班级中使用,但这不是必需的。
所以我的主要问题是:
我如何创建一个真实的callFunction
,可以将 任何 函数作为输入,以及该函数参数?
感谢任何帮助!
答案 0 :(得分:1)
你需要知道什么是返回和参数类型。固定在类或模板参数中。
这是在课堂上修复的一个例子:
struct foo {
foo(std::function<int(std::string, double)> func) : bar{std::move(func)} {}
int callFunction(std::string s, double d) {
bar(std::move(s), d);
}
private:
std::function<int(std::string, double)> bar;
};
此方法不仅允许函数指针,还允许任何类似函数的对象,如lambda。
如果您不想修复类型,则可以使用模板指定要包装的函数对象的类型:
template<typename F>
struct foo {
foo(F func) : bar{std::move(func)} {}
template<typename... Args>
auto callFunction(Args&&... args) -> decltype(bar(std::declval<Args>()...)) {
return bar(std::forward<Args>(args)...);
}
private:
F bar;
};
template<typename F>
auto make_foo(F f) {
return foo<F>{std::move(f)};
}
此方法允许任何函数或类似函数的对象,并且也比其他解决方案更快,因为它不会拖动std::function
开销。这里的缺点是你必须使用make_foo
之前的C ++ 17。
然后您可以像上面这样使用上面的解决方案:
auto f1 = make_foo([](int i){ return i * 1.5; });
auto f2 = make_foo([]{});
double result = f1.callFunction(12);
f2.callFunction();
如果您打开C ++ 17的开关,那么您可以写下:
foo f1 = [](int i){ return i * 1.5; };
foo f2 = []{};
double result = f1.callFunction(12);
f2.callFunction();
请注意,f1
和f2
仍然是不同类型的实例。模板参数通过演绎隐藏。