2016-12-16 9 views
0

私は私の質問説明するために、次の例を与える:あなたは上記のコードから見ることができるようにクラスメンバ関数への関数ポインタを使用してC++関数を単純化するにはどうすればよいですか?

class Abc 
{ 
public: 
    int height(); 
    int width(); 
    int area(); 

}; 

typedef std::vector<class Abc> AbcArray; 

void obtain_selected_list_based_on_area(AbcArray& objArray, 
    std::vector<int> &listIndexArray) 
{ 
    std::vector<int> areaArray; 
    for(int i=0; i<objArray.size(); i++) 
      areaArray.push_back(objArray[i].area()); 

    function_select_list(areaArray,listIndexArray); 
} 

void obtain_selected_list_based_on_height(AbcArray& objArray, 
    std::vector<int> &listIndexArray) 
{ 
    std::vector<int> areaArray; 
    for(int i=0; i<objArray.size(); i++) 
      areaArray.push_back(objArray[i].height()); 

    function_select_list(areaArray,listIndexArray); 
} 

void obtain_selected_list_based_on_width(AbcArray& objArray, 
    std::vector<int> &listIndexArray) 
{ 
    std::vector<int> areaArray; 
    for(int i=0; i<objArray.size(); i++) 
      areaArray.push_back(objArray[i].width()); 

    function_select_list(areaArray,listIndexArray); 
} 

は、我々は、3つの異なる基準に基づいてリストを選択することを決定しました。そのためには、obtain_selected_list_based_on_areaobtain_selected_list_based_on_height、およびobtain_selected_list_based_on_widthの3つの関数を記述する必要があります。
私はそれをどのように単純化することができますか?
私のために1つの解決策。

void obtain_select_list(AbcArray& objArray, std::vector<int> &listSel, FUN fun) 
{ 
    std::vector<int> areaArray; 
     for(int i=0; i<objArray.size(); i++) 
       areaArray.push_back(objArray[i].width()); 

     function_select_list(areaArray,listIndexArray); 

} 

しかし、私は関数ポインタは、クラスのメンバーを指しているので、それを動作させることはできません。一つは、関数ポインタを使用することです。
動作させる方法についていくつか考えていますか?さらに、この問題の他の解決策はありますか?

+1

関数ポインタを渡す代わりに、適切なメソッドを持つクラスのインスタンスへの参照を渡し、 'obtain_select_list()'メソッドをインスタンスに対して呼び出すようにすることができますその仕事をしなさい。 –

+0

...また、関数をコンパイル時(テンプレート)パラメータとして渡します。既知の関数を呼び出す方が速いです:fnptrは仮想呼び出しほど遅いです! – lorro

+0

トピック以外:IMHO、あなたは 'unsigned int'を' height'、 'width'、' area'に使うべきです。 'int'型は負の数を許します。私はまだ負の高さ、幅、または領域を見ていません。 –

答えて

2

正確に関数ポインタではなく、むしろクラスメソッドポインタです。

また、C++ 11の範囲の繰り返しが結果の構文がはるかに簡単になり、読みやすくを使用して:

void obtain_selected_list_based_on(AbcArray& objArray, 
    std::vector<int> &listIndexArray, 
    int (Abc::*get_something)()) 
) 
{ 
    std::vector<int> areaArray; 

    for (const auto &v:objArray) 
      areaArray.push_back((v.*get_something)()); 

    function_select_list(areaArray,listIndexArray); 
} 

これのように呼び出すことができます。

obtain_selected_list_based_on(objArray, 
           listIndexArray, 
           &Abc::height); 

// or 

obtain_selected_list_based_on(objArray, 
           listIndexArray, 
           &Abc::width); 

// or 

obtain_selected_list_based_on(objArray, 
           listIndexArray, 
           &Abc::area); 

あなたのクラスメソッドは、おそらく必要がありますconstとなり、パラメータタイプがint (Abc::*get_something)() constに変更されます。

0

私はこれがうまくいくと思います。

void <template T> obtain_select_list(AbcArray& objArray, std::vector<int> &listSel, T (*fun)(const Abc&)) 
{ 
    std::vector<T> areaArray; 
     for(int i=0; i<objArray.size(); i++) 
       areaArray.push_back(fun(objArray[i])); 

     function_select_list(areaArray,listIndexArray); 

} 

はちょうどあなたがint型から異なるものを返すように機能が必要な場合は、あなたはまだそれを使用できるように、私は、テンプレート1を使用し、より一般的です。

私はそれをテストすることができませんでした、それはコンパイルされますが、私はそれが動作すればわからないが、それはすべきです。

+0

OPはメソッドポインタ 'T(Abc :: * method)()const'を要求します – Stargateur

+0

@Stargateur私は彼が言ったことを推測します:"さらに、この問題に対する他の解決策はありますか? – Amadeus

+0

@Amadeusそれは彼のコードのより近くです。しかし、実際に彼は何かを尋ねる。 – Stargateur

関連する問題