0

大きなライブラリに新しいモジュールを追加しています。ここにあるすべてのメソッドは、静的として実装されています。簡略化されたモデルについて簡単に説明します。

typedef std::vector<double> TData;
double test ( const TData &arg ) { return arg ( 0 ) * sin ( arg ( 1 ) + ...;}
double ( * p_test ) ( const TData> &arg) = &test;

class A
{
    public:
      static T f1 (TData &input) {
         .... //some computations
         B::f2 (p_test);
      }
};

内部f1()でいくつかの計算が実行され、静的メソッドB::f2が呼び出されます。f2メソッドは別の作成者によって実装されており、いくつかのシミュレーション アルゴリズムを表しています (ここでの例は単純化されています) 。

class B
{
    public:
      static double f2 (double ( * p_test ) ( const TData  &arg ) )
      {
          //difficult algorithm working p_test many times
          double res = p_test(arg);
      }
};

f2メソッドには、いくつかの重み関数へのポインターがあります (ここでは) p_test。しかし、私の場合、メソッドのf1ために計算されたいくつかの追加パラメータが必要ですtest()

 double test ( const TData &arg, const TData &arg2, char *arg3.... ) { }

メソッドのソースコードの変更(簡単ではない)、ライブラリの再設計、および汚いハックなしで回避するtest()ために、これらのパラメータを(などに)注入する方法:-) ?f2f2

最も簡単な手順はオーバーライドすることですf2

static double f2 (double ( * p_test ) ( const TData  &arg ), const TData &arg2, char *arg3....  )

しかし、後で何をしますか?メソッドは静的であるため、オブジェクトに問題があると考えてください。


更新された質問

テンプレートパラメータに依存する関数へのポインタを作成したり、そのようなことをしたりすることは可能ですか?

if (condition) res = p_test(arg);
else res = p_test2(arg, arg2, arg3);
4

2 に答える 2

1

「変更を避ける」、それは少し難しいです。

ただし、静的変数を使用して、引数を渡さない関数の呼び出し間で引数を渡すことができます。

これらの関数を使用するスレッドが複数ある場合は、スレッドローカルストレージ(これは私が推奨するものです)を使用するか、単一の変数の場合はこれらの変数を使用するための適切な相互排除を確保する必要があることに注意してくださいすべてのスレッド間で共有されるということは、コールチェーン全体で除外されることを意味します。ただし、スレッド化に問題がある場合は、スレッドローカルストレージを使用してください。糸脱毛の問題がなければ、まあ、問題ありません!:-)

于 2012-10-05T09:36:28.417 に答える
1

汚いハックなし

起こらない。関数ポインターを受け取る関数のソースを変更できない場合は、追加の引数を取得するために例外 vomit を使用する必要があります。をサポートする C++11 コンパイラ (まだ存在していません) がある場合thread_local、理論的にはより適切な処理を行うか、OS 固有の TLS を使用することができます。しかし、現在のところ、移植可能な唯一の解決策は例外的な嘔吐です.

void f(void(*fp)()) { fp(); }
void mah_func() { 
    try { 
        throw; 
    } catch(my_class* m) {
        m->func();
    }
}
int main() {
    my_class m;
    try {
        throw &m;
    } catch(my_class* p) {
        f(mah_func);
    }
}

あるいは、あなたのシナリオでは、変更f2は不可能ではなく、難しいだけのようです。ただし、それを変更して a を取ることの難しさはstd::function<double(const TData&)>非常に低くなります。演算子のオーバーロードのおかげで、引数の型を変更するだけで済みます。関数パラメーターの型を変更するだけで、すべての呼び出しサイトが引き続き機能するなど、複雑な関数でも非常に単純な変更である必要があります。その後、bindまたはラムダまたはを介して作成された適切な関数オブジェクトを渡すことができます何か。

于 2012-10-05T09:44:47.880 に答える