1

カスタム補完を簡単に使用できるように GNU Readline 用の c++ ラッパーを作成しようとしていますが、小さな問題に遭遇し、解決策が思いつきません (私はまだ c++ に慣れていません)。

class ReadLine {

public:

    ReadLine();
    ~ReadLine();

    std::string exec ();
    void enableHistory ();

private:
    std::vector<std::string> keywordList;
    bool history;

private:
    static char** my_completion (const char*, int, int);
    void* xmalloc (int);

    char* generator (const char*, int);
    char* dupstr (std::string);

};

cpp ファイル:

std::string ReadLine::exec(){

    rl_attempted_completion_function = my_completion;

    std::string buf = "";

    buf = readline("Command>>");
    //enable auto-complete
    rl_bind_key('\t',rl_complete);

    if (buf[0]!=0)
        add_history(buf.c_str());

    return buf;
}




char** ReadLine::my_completion (const char* text, int start, int end) {


    char** matches;

    matches = NULL;

    if (start == 0) 
        matches = rl_completion_matches(text, my_generator);

    return matches;


}

私の問題はラインです

マッチ = rl_completion_matches(テキスト, my_generator)

明らかにエラーがスローされます:call to non-static member function without an object argumentしかし、ジェネレーターを静的にしたくありません。また、ジェネレーター内のクラス メンバーにアクセスできないため、必要な引数を見つけることができません (キーワードを生成するには、keywordlist が必要です)。 )。

何を提案しますか?

4

1 に答える 1

0

通常の解決策は、クラスへのポインターを引数として渡す静的ラッパー関数を使用して解決することであるため、これを適切に解決するのは簡単ではありません。

他の誰かがより良いものを思い付くことができるかもしれませんが、解決策は、現在の ReadLine クラス インスタンスへのポインターであるグローバル変数を持つことだと思います。これはスタックである可能性があるため、新しいものをそれにプッシュできます。それが終わったら、ポップして古いものに戻します。

単純なケースでは、次のようになります。

ReadLine *currenReadLine = 0;

.... 

std::string ReadLine::exec(){
   ... 
   currentReadLine = this;
}


// declared as static in the class.
char ** ReadLine::my_completion(...)
{
    return currentReadLine->actual_completion(...);
}

と同様のソリューションですmy_generator

于 2013-08-05T08:42:47.943 に答える