2017-01-28 2 views
4

Я пытаюсь передать метод как функцию указателя, поэтому я создал связующее, как показано here, но поскольку метод определен, я не могу передать его как параметр в связующее. Функция, которую мне нужно передать указатель метода, связана с библиотекой шаблонов Regex Lua для arduino, найденной here.Передача метода typedef в качестве функции указателя

void InterpreterClass::init() 
{ 
    MatchState ms("255.255.255.255"); 

    bind_regex_member<InterpreterClass, &InterpreterClass::MatchAddressCallback, 0> b(this); 
    ms.GlobalMatch("(%d%d?%d?)", b); 
} 

void InterpreterClass::MatchAddressCallback(const char * match, const unsigned int length, const MatchState & ms) 
{ 
    //do something 
} 

на ms.GlobalMatch второй параметр является метод, который я хочу, чтобы выполнить после того, как строка интерпретируется, проблема заключается в том, что функция должна выполнять определенную последовательность параметров, как если бы он был «делегированных».

typedef void (*GlobalMatchCallback) (const char * match,   // matching string (not null-terminated) 
            const unsigned int length, // length of matching string 
            const MatchState & ms);  // MatchState in use (to get captures) 

Я попытался реализовать связующее со всеми объявленными параметрами и с объявленным им именем типа. Пыльник следует связующее:

template<class T, void(T::*PTR)(const char *, const unsigned int, const MatchState &), size_t I> 
struct bind_regex_member 
{ 
    typedef void(*fn_type)(const char *, const unsigned int, const MatchState &); 
    explicit bind_regex_member(const T* _ptr) 
    { 
     ptr = _ptr; 
    } 
    static void func(const char * match, const unsigned int length, const MatchState & ms) 
    { 
     (ptr->*PTR)(match, length, ms); 
    } 
    operator fn_type() 
    { 
     return &func; 
    } 
private: 
    static const T* ptr; 
}; 

template<class T, void(T::*PTR)(const char *, const unsigned int, const MatchState &), size_t I> 
const T* bind_regex_member<T, PTR, I>::ptr = NULL; 

Первая ошибка, что компилятор показывает, является:

Error: `Interpreter.cpp:7:80: error: could not convert template argument ‘&InterpreterClass::MatchAddressCallback’ to ‘void (InterpreterClass::*)(const char*, unsigned int, const MatchState&)’` 

Изготовление связующего вещества к GlobalMatchCallback не работает либо. Что я должен сделать для MatchAddressCallback?

Минимальный код проекта repo: https://github.com/rsegecin/RegexArduino.git.

PS: Мне было очень трудно выразить себя с таким типом проблемы, поэтому любая обратная связь приветствуется.

ответ

4

Проблема заключается в том, что ptr в bind_regex_member указывает на const T и ваш метод InterpreterClass :: MatchAddressCallback не const. Основном, как это:

InterpreterClass i; 
const InterpreterClass* myPtr = &i; 
MatchState myMs; 
myPtr->MatchAddressCallback("", 0, myMs); // OUCH! myPtr points to const T and MatchAddressCallback is non const member function 

Удалить константным из PTR в bind_regex_member и он должен работать!

EDIT: Существует вторая проблема в Interpreter.h:

class Interpreter 
{ 
public: 
    void init(); 
    GlobalMatchCallback MatchAddressCallback; // <----------- HERE 
}; 

Вы не можете объявить метод как это. «Окончательный» Interpreter.h должен выглядеть следующим образом:

#ifndef _INTERPRETER_h 
#define _INTERPRETER_h 

#include <Arduino.h> 
#include "Regexp.h" 

template<class T, void(T::*PTR)(const char *, const unsigned int, const MatchState &), size_t I> 
struct bind_regex_member 
{ 
    typedef void(*fn_type)(const char *, const unsigned int, const MatchState &); 
    explicit bind_regex_member(T* _ptr) 
    { 
     ptr = _ptr; 
    } 
    static void func(const char * match, const unsigned int length, const MatchState & ms) 
    { 
     (ptr->*PTR)(match, length, ms); 
    } 
    operator fn_type() 
    { 
     return &func; 
    } 
private: 
    static T* ptr; 
}; 

template<class T, 

void(T::*PTR)(const char *, const unsigned int, const MatchState &), size_t I> 
T* bind_regex_member<T, PTR, I>::ptr = NULL; 

class InterpreterClass 
{ 
public: 
    void init(); 

    void MatchAddressCallback(const char * match, const unsigned int length, const MatchState & ms); 
}; 

extern InterpreterClass Interpreter; 

#endif 
+0

Я сделал, как вы сказали, но я все еще получаю ту же ошибку, что кстати, я сказал, что проблема была, но я забыл после того, что ошибка вертела компиляции вне. Ошибка: 'Interpreter.cpp: 7: 80: ошибка: не удалось преобразовать аргумент шаблона '& InterpreterClass :: MatchAddressCallback' to 'void (InterpreterClass :: *) (const char *, unsigned int, const MatchState &)'' –

+1

Я отредактировал мою ответ! – Salco

+0

Большое спасибо Salco. –

Смежные вопросы