0

n 変数の関数があるとします。

y = f (x1, ..., xn) 

このような関数を引数として渡したいと思います。

Matlab では、ハンドルを使用した次の構築が利用可能です。

function y=func(x)
y = sin(x(0)) * cos(x(1))  //Any definition, not important

p_func=@func; //Define handle

ハンドルを別の関数のパラメーターとして使用することができます。

y = function2(p_func, n);

ここで、n は次元を表します...

C++ を使用してこのコードを書き直す方法は? 関数テンプレートで単純なモデルを使用します

temmplate <typename T>
T func( const T *arg, const short n) {return sin(arg[0]) * cos(arg[1])};

ここで、xi 引数は n 要素の 1 次元配列で表されます。問題は、この場合、関数テンプレートへのポインターを使用できないことです。

template <class T>
static T ( *pfunc ) ( const T *arg, const short n )

専門分野のみ...おそらく別のモデルがより適切かもしれません...助けてくれてありがとう...

備考: クラステンプレートが有用であることは知っています

template  <typename T>
class Foo
{ 
    T func( const T *args, const short n);
};

そして、この構築は機能します:

template <class T>
static T ( *pfunc ) ( const T *arg, const short n )

ただし、ライブラリの現在のモデルでは使用されていない可能性があります (これには影響しません)。

4

4 に答える 4

3

C++ は静的に型付けされた言語です。C++ のすべてのオブジェクトは、関数ポインターであろうと何であろうと、特定の型を持っている必要があります。また、関数ポインタの型は、指し示す関数が与えられる引数の型に基づいています。

テンプレートはオブジェクトではないため、テンプレートへのポインターを取得することはできません。テンプレートのインスタンス化へのポインターを取得できます。あなたのfunc定義を使用すると、 とfunc<int>を取る関数です。へのポインタを取得できます。しかし、テンプレートです。テンプレートへのポインタを取得できません。const int*shortfunc<int>func

そのため、C++ プログラムは関数ポインターの代わりにファンクターをスローすることがよくあります。ファンクターはテンプレートoperator()メソッドを持つことができるため、テンプレート関数を渡すように呼び出すことができます。しかし、関数ポインターを使用する必要があると言うので、できることはあまりありません。

于 2012-10-01T19:31:47.943 に答える
1

テンプレートはオブジェクトではないため、テンプレート関数へのポインターを取得することはできません。これは、複数の特定の関数を生成するコンパイル時の構文構築であるためです-テンプレートのインスタンス化。たとえば、テンプレートのインスタンス化f<int>(const int*, short)はオブジェクトであり、参照できます。

テンプレートのインスタンス化から関数ポインターを取得するための単純で統一された方法が必要な場合は、次を使用declspec()します (最新の C++11 互換コンパイラーを使用していると仮定しています)。

template <class T> static T f(const T *, const short )
{
  // Implementation
  ...
}

// Declaring function pointers for int & double
typedef decltype(&f<int>) IntFuncPtr;
typedef decltype(&f<double>) DoubleFuncPtr;

// Sample usage
IntFuncPtr intFunc = &f<int>;
intFunc(NULL, 0);

DoubleFuncPtr doubleFunc = &f<double>;
doubleFunc(NULL, 0);
于 2012-10-01T19:55:37.090 に答える
1

これは C++ で簡単に解決できるとは思いませんが、同様のケースに対するアプローチはあります。boost::bind および boost::functionライブラリを見てください。これは、C++ で関数ポインターを渡すという厄介な詳細を回避するために作成されました (また、クラス メソッドも渡すことができます)。私が思い出す限り、彼らは実際には一般的な N を使用していませんが、任意の N パラメータのテンプレートをインスタンス化しています。似たようなものを手に入れたい場合は、一見の価値があります。

于 2012-10-01T19:30:52.343 に答える
1

問題は「n」ではありません。問題は、テンプレート化された型 T です。

ここで、(関数へのポインタ型の) 変数を宣言しようとしていますか?

template <class T>
static T ( *pfunc ) ( const T *arg, const short n )

これは、テンプレートをインスタンス化しないと機能しません。

そうしないと、型チェックが不可能になるからです。型チェッカーは、ポインターを初期化したとき、T が逆参照したときと同じかどうかをチェックできませんでした。

おそらく、より大きなコンテキストを見る必要があります。その宣言をどこで使用しますか? テンプレート パラメータをそのコンテキストに移動します。

たとえば、テンプレート パラメーター T を持つ関数またはクラスを使用できます。そこで、型のどこかに T を持つ関数ポインターを宣言、初期化、および逆参照することができます。

関数ポインターを割り当てた場所でパラメーターを「バインド」できるかもしれません。したがって、結果の関数は nullary 関数になり、パラメーターの型を知らなくても使用できます。

于 2012-10-01T19:44:43.950 に答える