我想要以下内容:
void foo(
/* something representing a function f */,
/* arguments a1, a2, etc. in some form */ )
{
/* magic - invoke f(a1, a2, etc.)*/
}
/* ... */
void bar(float f, char* s);
void baz(int i);
/* etc. */
int main() {
/* ... */
foo(bar, SomeKindOfTransformationOrNoneAtAll(f, s));
foo(baz, SomeKindOfTransformationOrNoneAtAll(i));
/* etc. */
}
我可以实施foo()
吗?也就是说,我可以编写一个函数,它接受一个任意的其他函数,一堆参数(varargs,或vector,或者,或者你有什么),并使用传递的参数调用传递的函数?
如果可以的话,是否有一个便于它的图书馆?还是一些常见的习语?
注意:
foo()
必须不仅仅需要一个函数* / std :: function / etc.参数。答案 0 :(得分:3)
Variadic模板确实可以做到这一点。
template<typename T, typename... Args> void foo(T func, Args&&... args) {
func(std::forward<Args>(args)...);
}
然后直接将参数传递给foo
。这称为完美转发。然而,对于lambdas来说,将它们绑定在那里真的更惯用。
template<typename T> void foo(T func) {
func();
}
int main() {
foo([] { baz(param1, param2); });
}
如果它们不是常数,你可以捕获它们。这是一个很好的选择,因为如果需要,您可以轻松地将模板转换为非模板,并且可以避免参数生存期与否的问题,因为lambda用户可以捕获它们所需的。您可以采用这种方式而不是仅使用一个对象,因为可变参数包只能出现一次。最后,在使用命名函数时,你不需要选择单个函数指针。
答案 1 :(得分:0)
您似乎在寻找std::bind
。
所以,比如:
void foo(std::function<void()> fun) {
fun();
}
foo(std::bind(bar, 0.1f, "abc"));
foo(std::bind(baz, 42));
答案 2 :(得分:0)
如果我理解正确,你想在调用者的网站上决定应该调用哪个函数。
最简单的解决方案是使用带有std :: function的lambda:
void foo(std::function<void(void)> f) { // std::function has strong magic
// whatever you want here
f();
// whatever you want here
}
/* ... */
void bar(float f, char* s);
void baz(int i);
/* etc. */
int main() {
foo( [f, s]() { bar(f, s); } );
foo( [&i]() { baz(i) } );
/* etc. */
}