-1

我有一个问题继续作为模板参数传递的帖子函数。在提供的代码中:

#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++。

4

2 回答 2

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然后可以在不存储参数的情况下调用它。这与使用 type 的参数非常相似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变量并返回它。在这一点上,更容易将您引导到我之前关于此事的问题。我的用例被证明是没有实际意义的,但该解决方案适用于其他用途。

于 2013-02-06T05:02:13.687 回答
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;
}
于 2013-02-06T02:39:05.700 回答