2017-10-17 6 views
2

私がやっていることは、スワップと比較の数を含むアルゴリズムを解析する関数を作ることです。この関数を再利用するためにはアルゴリズムを解析するために各アルゴリズム関数を呼び出す必要があります。C++でメソッド内の関数を置き換える方法はありますか

bool flag = false; 
    for (int i = 0; i < 6; i++) 
    { 
     if (!flag) 
     { 
      selectionSort(bigArray[i], 100); 
      printData(fileNames[i],swaps,comparisons); 
      comparisons = 0; 
      swaps = 0; 
      flag = true; 
     } 
     else 
     { 
      selectionSort(bigArray[i], 1000); 
      printData(fileNames[i],swaps,comparisons); 
      comparisons = 0; 
      swaps = 0; 
      flag = false; 
     } 
    } 

は今、あなたは選択ソートは、私が数え、挿入、迅速、ヒープと、それを置き換えるマージする必要があります。ここで参照してください。ここでは

は、関数のコードです。私はちょうどメインに何度も何度もコードを書いてソート機能を置き換えることができますが、これを行うための解決策がいくつかあるはずです。私はそれを見つけることができません、私はパラメータとして別の関数を取る関数を作ることを考えていたが、再び、いくつかのアルゴリズムの機能は2つの他の3を取る、そしてそれを行うときにあなたはすることができない void analyzeAlgorithms(void (*function)(int*, int, int, int x = 0)). (私はいくつかの無関係なものを省略)のおかげで、事前

+0

なぜあなたは関数ポインタを使用することはできませんか?あなたの関数の中にはいくつかの関数が2つあり、3つの引数を取るものがある場合は、3つ目のパラメータをオプションにして、必要なときに無視します。 – Alex

+0

もう一つの選択肢は、バリデーションテンプレートパラメータパックを持つ関数を作成し、それを対応する 'std :: function'パラメータに転送することです。 – user0042

+0

@Alex私がポインタ関数を使用する場合、私はいくつかのアルゴリズムは2または3を取ると述べたように。 C++コンパイルでは、\t関数(bigArray [i]、100、????????)のようなパラメータを実装する必要がありました。 –

答えて

2

にあなたは可変引数パラメータセットを取る関数テンプレート内のコードをラップすることができ、かつマッチングFn呼び出し可能パラメータにそれを転送し、それを認めることになります。

#include <iostream> 

template<typename Fn, typename ...Args> 
void sort_tester(Fn sortfunc, Args... args) { 
    int bigArray[] {1,2,3,4,5,6}; 
    bool flag = false; 
    for (int i = 0; i < 6; i++) { 
     int n = flag ? 1000 : 100; 
     sortfunc(bigArray[i],n,args...); 
     flag = !flag; 
    } 
} 

void selectionSort(int elem, int n) { 
    std::cout << "selectionSort(" << elem << ',' << n << ")\n"; 
    // Do stuff ... 
} 

void mergeSort(int elem, int n, int extraParam) { 
    std::cout << "mergeSort(" << elem << ',' << n << ',' << extraParam << ")\n"; 
    // Do stuff ... 
} 

これは次のように使用できます。

int main() { 
    sort_tester(selectionSort); 

    sort_tester(mergeSort,42); 
} 

live exampleをご覧ください。

+1

代わりに 'std :: function'を使うのではなく、代わりに通常のテンプレートパラメータを使うことをお勧めしますか?今では、パラメータを完全に一致させるために 'Args'が必要であり、変換は許可されません。 'std :: function <...> 'を単純なテンプレートパラメータで置き換えると、変換が行われ、もっと軽いでしょう。 –

+0

'std :: function'は型の強制(あなたのユースケースに応じて良いか悪いか)を与えますが、余計な間接指定とヒープ割り当ても行います。 – caps

+0

@GuillaumeRacicotありがとうございました。私は今、 'std :: function'の代わりにプレーンなテンプレートパラメータを使ってコード例を単純化しました。 – user0042

1

あなたの関数の署名があれば助けになりましたので、変数の型とパラメータを仮定します。より完全なソリューションをご希望の場合は、質問を編集して実際の関連データを追加して問題を解決してください。

パラメータとして置き換える関数を渡すことができます。

それを呼び出すとき、あなたは関数やラムダを渡すことができ
template<typename F> 
void yourAlgorithm(char const** fileNames, int** bigArray, F function) { 
    bool flag = false; 
    for (int i = 0; i < 6; i++) 
    { 
     if (!flag) 
     { 
      function(bigArray[i], 100); 
      printData(fileNames[i],swaps,comparisons); 
      comparisons = 0; 
      swaps = 0; 
      flag = true; 
     } 
     else 
     { 
      function(bigArray[i], 1000); 
      printData(fileNames[i],swaps,comparisons); 
      comparisons = 0; 
      swaps = 0; 
      flag = false; 
     } 
    } 
} 

int n = 2; 
yourAlgorithm(fileNames, bigArray, selectionSort); 
yourAlgorithm(fileNames, bigArray, mergeSort); 
yourAlgorithm(fileNames, bigArray, [n](int* a, int x){ /* do stuff with a, b and n */ }); 
+0

私はOPの質問がどのようにさまざまな数のパラメータでソートアルゴリズム(関数)を呼び出すかということを理解しました。これは、可変パラメータパックIMOを暗示する必要があります。 – user0042

+0

@Guillaume Racicotあなたはパラメータを指摘していましたが(:しかし、user0042は正しいですが、関数はさまざまな数のパラメータ用です) –

+0

私はメソッドのテンプレートを使いますが、ここでは 'char * 'と' int * 'へのポインタは、配列参照を渡すための非常にクリーンな方法ではありません... – caps

関連する問題