-1

投稿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>();
}

パラメーター セットのレイアウトが異なる 3 番目の関数についてはどうでしょうか。たとえば、

double add3(double v1, double v2)
{
return v1+v2;
}

これがテンプレートを使用してもまったく達成できない場合、任意の関数を別の関数に渡すにはどうすればよいでしょうか? そして、あらゆる種類の可能性を持つパラメーター セットをどのように処理するのでしょうか? タプル(kwargs**)を渡すことでPythonがそれを実行できる可能性があることは知っていますが、C / C ++についてはわかりません。

4

2 に答える 2

1

呼び出されるジェネリック関数を渡す 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、2 つのパラメーターとそれにバインドされたパラメーターに与えられた値を持つラムダで呼び出されます。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 に答える