我有一个问题继续发布Function passed as template argument。在提供的代码中:
#include <iostream>
void add1(int &v)
{
v+=1;
}
void add2(int &v)
{
v+=2;
}
template <void (*T)(int &)>
void doOperation()
{
int temp=0;
T(temp);
std::cout << "Result is " << temp << std::endl;
}
int main()
{
doOperation<add1>();
doOperation<add2>();
}
具有不同参数集布局的第三个函数怎么样,例如
double add3(double v1, double v2)
{
return v1+v2;
}
如果根本无法使用模板实现这一点,我们如何将任意函数传递给另一个函数?我们如何处理具有各种可能性的参数集?我知道python可以通过传递一个元组(kwargs **)来实现,但不确定C / C ++。
答案 0 :(得分:1)
传递要调用的泛型函数的一种形式是可调用的模板化类型:
#include <functional>
#include <iostream>
template<typename F>
void callFoo(F f) {
f();
}
int main() {
callFoo(std::bind([](int a, int b) {std::cout << a << ' ' << b;}, 5, 6));
}
callFoo
采用可调用类型F
并调用它。例如,围绕此调用,您可以执行计时器工作以计时功能。在main
中,它被一个lambda调用,该lambda有两个参数,并且这些参数的值被绑定到它。然后callFoo
可以在不存储参数的情况下调用它。这与使用std::function<void()>
类型的参数非常相似。
但是,如果您不想使用std::bind
,则可以通过一些更改单独传递参数:
template<typename F, typename... Args>
void callFoo(F f, Args... args) { //ignoring perfect forwarding
f(args...);
}
int main() {
callFoo(/*lambda*/, 5, 6);
}
在这些情况下,传递void函数是有意义的。实际上,返回值可以用作参数并通过std::ref
传递。如果您计划返回函数返回的内容,则必须处理返回类型为void
的特殊情况,因为您无法分配给void
变量并返回该变量。此时,您可以更轻松地将您引导至previous question。我的用例结果证明是没有实际意义,但该解决方案非常适合其他用途。
答案 1 :(得分:0)
这可能会让你更接近你想要的东西:
#include <iostream>
void add1(int &v)
{
v+=1;
}
double add2(double v1, double v2)
{
return v1 + v2;
}
// 1 param version
template< class aRetType, class tP1 >
aRetType doOperation( aRetType (*aFunction)( tP1 aP1 ), tP1 valP1 )
{
return aFunction( valP1 );
}
// 2 param version
template< class aRetType, class tP1, class tP2 >
aRetType doOperation( aRetType (*aFunction)( tP1 aP1, tP2 aP2 ), tP1 valP1, tP2 valP2 )
{
return aFunction( valP1, valP2 );
}
// 3 param version and up is not given, but you get the trick.
int main()
{
int iTemp = 8;
doOperation< void, int& >( add1, iTemp );
std::cout << "Result is " << iTemp << std::endl;
double iResult;
iResult = doOperation< double, double, double >( add2, 2.2, 8.8);
std::cout << "Result is " << iResult << std::endl;
}