2017-08-10 14 views
0

私はメニューと呼ばれるクラスを持っています。ここにそれのヘッダ実装があります。コールバックの名前空間を置き換えるテンプレート? cpp

class Menu{ 
private: 
    int last_mouse_active_hold_x; 
    int last_mouse_active_hold_y; 

public: 
    float x; 
    float y; 
    float width; 
    float height; 
    int  x_full; 
    int  y_full; 
    int  width_full; 
    int  height_full; 
    bool is_shown; 

    int  num_of_items_shown; 
    int  height_per_item_full; 
    float height_per_item; 
    int  item_offset; 
    int  selected_index; 
    float outside_scroll_speed; 
    int  scroll_speed; 
    int  scroll_counter; 


    std::string  name; 
    unsigned char shortcut; 
    std::string  search_term; 

    MenuItem * items; 
    int   items_len; 
    MenuItem * items_full; 
    int   items_full_len; 

       Menu(); 
    void  render(); 
    void  set_pos(float x, float y); 
    void  set_pos(int x, int y); 
    void  set_width(float w); 
    void  set_name(std::string _name); 
    void  reshape(); 
    void  show(); 
    void  hide(); 
    void  toggle_show(); 
    void  add(std::string _name, int (*_callback)(std::string), std::string _callback_param); 
    void  select(int _index); 
    void  set_number_of_items(int _n); 
    void  set_height(int _h); 
    void  set_width(int _w); 
    void  set_shortcut(unsigned char c); 
    void  mouse_move_passive(int _x, int _y); 
    void  mouse_move_active(int _x, int _y); 
    void  mouse_press(int _button, int _state, int _x, int _y); 
    void  key_press(unsigned char _key, int _x, int _y); 
    void  key_press_special(unsigned char _key, int _x, int _y); 
    void  scroll(int _ammount); 
    void  search(); 
    void  refill_items(); 
    void  pop_item(int _i); 
    void  trigger(); 

メニューには、MenuItemのリストがあります。私は余分なデータがこの問題に関連しているとは思わない。ここで

は、MenuItemのヘッダファイルです:

class MenuItem{ 
public: 
    std::string  name; 
    int    (* callback)(std::string); 
    std::string  callback_param; 
    int    x_full; 
    int    y_full; 
    int    width_full; 
    int    height_full; 
    float   x; 
    float   y; 
    float   width; 
    float   height; 
    float   text_size; 
    float   text_margin_left; 
    float   text_margin_bottom; 
    bool   selected; 

      MenuItem(); 
    void create(std::string _name, int (*callback)(std::string) ); 
    void render(float _x, float _y, float _z); 
    void reshape(); 
    void set_size(int _w, int _h); 
    void set_height(int _h); 
    void set_param(std::string _p); 
    int  trigger(); 

}; 

さて、これが邪魔であることを、私は私の実際の問題に取得することができます。 問題は、MenuItemクラスのコールバック関数内にあります。 コールバックは、これがすべていいです、私はそれを与えている機能は、メインのコードの一部である、またはクラス内の静的であれば正常に動作タイプの何か

int (*callback(std::string a))

を期待しています。しかし、私の目標は、このメニューを他のクラスに保存して、独自のメソッドをいくつか渡すことができるようにすることです。それを使用したいと思い、ほとんど私のクラスのために、彼らはタイプ

int (* BaseClass::callback(std::string a))

のコールバックに渡すので、これはそのため、私は私が間違った種類を渡していますと言って、コンパイルエラーを取得し、問題となっていますコールバックオブジェクトとしてのメニュー。

どうすれば対処できますか?私が検討した1つのオプションは、MenuおよびMenuItemクラスにテンプレートを追加することです。私はすでに多量のコードを書いているので、このオプションを避けたいと思います。(あまりにも愚かではなく)リファクタリングは時間を浪費します。これはテンプレートでも可能でしょうか?オブジェクトタイプではなく名前空間としてテンプレートを使用できますか?

ここに他にどのようなオプションがありますか?

+0

としてラムダ/ファンクタを渡すことができますか? C++ 11以上を使用している場合は、ラムダ関数を使用して、ラムダでキャプチャされたオブジェクトの適切なメンバ関数を呼び出すことができます。 – dlasalle

+0

C++を使用しないでください。これは良い選択ですが、私は将来を考えています。 – suli

+0

公開されているデータmeberはほとんど決して良い考えではありません...そしておそらく関数の3/4はプライベートでなければなりません。メンバ関数へのポインタが必要な場合は、コードを更新してください。**リファクタリングは時間の無駄ではありません。**あなたが悪いコードを残しておけば、将来的には修正する時間が長くなります。 – Phil1970

答えて

1

あなたはstd::functionを使用する可能性があります:

std::function<int(std::string)> callback; 

ユーザーはまだあなたがC++標準のどのバージョンを使用している

menuItem.setCallback([this](std::string a) { return this->my_callback(a); } 
+0

私はラムダの解決策が正しいと思いますか?しかし、私はstd :: functionソリューションが好きです。基本的に私はメニューとMenuItemクラスを変更してstd :: functionの権利を取りますか?それはコールバックでしょうか? – suli

+0

std :: functionは素晴らしいですが、コールバックがオーバーロードされたメンバー関数なので、私の場合は機能しません。コンパイルエラーが発生します。しかし、あなたの答えのおかげで、私はラムダ関数を読みました。本当にありがとう !これは動作します – suli

+0

ラムダとstd :: functionは確かにC++ 11です。 – Jarod42

関連する問題