Я пытаюсь написать оболочку c ++ для GNU Readline, чтобы иметь возможность легко использовать пользовательское завершение, но столкнулся с небольшой проблемой и не могу придумать решение (я все еще новичок в 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;}
Моя проблема в линии
match = rl_completion_matches (text, my_generator)
Это очевидно выдает ошибку: call to non-static member function without an object argument
но я не хочу делать генератор статическим и не могу найти, какие аргументы он должен использовать, потому что я не смогу получить доступ к членам класса внутри него (мне нужен список ключевых слов для генерации ключевых слов).
Что ты предлагаешь?
Нелегко решить эту проблему хорошим способом, поскольку нормальное решение — решить ее, используя статическую функцию-обертку, в которой вы передаете указатель на класс в качестве аргумента.
Кто-то может быть в состоянии придумать что-то лучше, но я думаю, что решение состоит в том, чтобы иметь глобальную переменную, которая является указателем на текущий экземпляр класса 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
,
Других решений пока нет …