Указатель на функцию в параметре - PullRequest
1 голос
/ 23 августа 2010

Мне нужно сделать функцию, которая добавляет указатель функции на карту.Это было бы примерно так:

bool RegisterFunction (string name, FunctionPointer function).

Но у меня проблема с вызовом, потому что я не знаю, как передать ему функцию вместо результата функции (когда я вызываю это как здесь:

RegisterFunction ("run", Run()) 

не работает, не работает Run без скобок, а также:

  • * Run ()
  • & Run ()
  • * Выполнить
  • & Выполнить

Как это исправить?

Редактировать:
Ошибка:

parser.cpp|9|error: no matching function for call to  
    'MCXJS::Parser::RegisterFunction(const char [4], <unresolved overloaded function type>)'| 

Функция RegisterFunction ()) и функции Run () находятся в классе Parser, который находится в пространстве имен MCXJS.
Тело класса:

class Parser  
{  
    public:  
    Parser ();  
    CVariable RegisterFunction (FunctionPointer);  
    bool RegisterErrorHandler (ErrorType, ErrorHandlerPointer);  
    CVariable Run (std::string);  
    bool AlwaysDefaultErrorHandler;  
    int MaxCallStackSize;  
    private:  
    std::map <std::string, FunctionPointer> ExternalFunctions;  
    std::map <ErrorType, ErrorHandlerPointer> ErrorHandlers;  
    ErrorHandlerPointer DefaultErrorHandler;  
};  

И файл parser.cpp:

Parser::Parser ():  
    AlwaysDefaultErrorHandler (true), MaxCallStackSize (4)  
{  
    RegisterFunction ("run", Run);  
};  

CVariable Parser::Run (std::string path)  
{  
    return 5;  
};  

Typedefs:

typedef CVariable (*FunctionPointer) (std::string);  
typedef void (*ErrorHandlerPointer) (ErrorData);  

Ответы [ 3 ]

3 голосов
/ 23 августа 2010

Run - это нестатическая функция-член, а не обычная функция, поэтому либо вы регистрируете что-то неправильного типа, либо вам нужно изменить typedef для ссылки на указатель на член.

* 1005 Е.Г. *

typedef CVariable (Parser::*FunctionPointer) (std::string);

Тогда правильный способ формирования указателя на член будет:

RegisterFunction("run", &Parser::Run);

Обратите внимание, что вы должны использовать оператор .* или ->* с указателем на объект или объект соответственно для вызова функции-члена через указатель на член.

1 голос
/ 23 августа 2010
RegisterFunction ("run", Run)

- правильный метод.Какую ошибку вы получаете, используя это?

Я подозреваю, что проблема не в том, как вы вызываете RegisterFunction, а в том, как вы ее определяете.Вы даете нам это:

RegisterFunction (string name, FunctionPointer function). 

, но пропускаете декларацию FunctionPointer.Это должно быть определено что-то вроде:

typedef void (*FunctionPointer)()

Предполагая, что Run определено как:

 void Run();

Обратите внимание, что для этого нужно, Все из функций, которые вы используете с RegisterFunction, должна иметь одинаковую подпись.

ОБНОВЛЕНИЕ: Судя по сообщению об ошибке, которое вы предоставили в комментарии, проблема заключается в том, что у вас более одной функции «Выполнить»,и компилятор не знает, какой из них вы хотите передать.(К сожалению, я не уверен, как вы это поясните, поэтому вы можете переименовать одну из них)

Одна вещь, которую вы можете попробовать:

 RegisterFunction (std::string("run"), Run);

Учитывая точноесоответствует первому параметру; возможно, можно выбрать, какую Run функцию, на основе которой будет соответствовать подпись в FunctionPointer.

ОБНОВЛЕНИЕ2: Вам нужно либо сделать Parser :: Run () статическимфункция, это изменение объявления FunctionPointer на:

 typedef CVariable (Parser::*FunctionPointer) (std::string); 
0 голосов
/ 23 августа 2010

Вы можете просто передать имя функции без каких-либо декораций или скобок:

RegisterFunction(name, Run);

Однако должно работать и следующее:

RegisterFunction(name, &Run);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...