因此,如果我们想编写自己的函数,似乎ANTLR3C使用函数指针来允许用户覆盖它们。我需要覆盖错误报告功能:
指针
void(*displayRecognitionError)(struct ANTLR3_BASE_RECOGNIZER_struct * recognizer,
pANTLR3_UINT8 * tokenNames);
功能
static void displayRecognitionError (pANTLR3_BASE_RECOGNIZER recognizer,
pANTLR3_UINT8 * tokenNames);
现在我有以下内容:
@lexer::apifuncs {
RECOGNIZER->displayRecognitionError = displayRecognitionErrorNew;
}
@lexer::includes {
#include "lexerData.h"
static void displayRecognitionErrorNew (pANTLR3_BASE_RECOGNIZER recognizer,
pANTLR3_UINT8 * tokenNames);
}
@lexer::members {
#include "lexerError.h"
}
使用lexerError.h文件中的新错误代码(全部有效)。我试图通过移动lexerData类中的错误函数来改变它,但不幸的是,当我尝试将函数指针设置为类成员时,我得到了编译错误。
compileUnit.cpp:179:62: error: argument of type ‘void (lexerData::)(ANTLR3_BASE_RECOGNIZER_struct*, uint8_t**)’ does not match ‘void (*)(ANTLR3_BASE_RECOGNIZER_struct*, uint8_t**)’
据我所知,这不是一个简单的转换或语法问题。我应该怎么做才能允许这个?一个修复似乎是更改函数指针定义,但我需要能够将函数指针分配给不同的类,因为词法分析器使用不同的数据结构运行两次。
答案 0 :(得分:1)
通常,不可能简单地将成员非静态函数的地址分配给指向非类函数的指针。您可以创建非类函数,该函数将调用lexerData类的正确成员函数。问题是这个非类函数必须能够以某种方式引用lexerData对象。我对ANTLR3C一无所知,所以不幸的是,我无法就此提出具体的建议:(
答案 1 :(得分:1)
答案在于question。
boost::bind
也可以帮到你。我虽然没有太多关于它的信息。
答案 2 :(得分:0)
在C ++中,类的每个成员函数都有一个隐藏参数。它是指向类实例(this
)的指针。此功能的实现未标准化,因此您不能假设此类参数可以某种方式“找到”某些特定签名,例如int foo(const MyClass*, int, int);
而不是int foo(int, int);
用于类MyClass
。
通常这意味着如果你有一个类的成员函数并且想要指向它的指针,那你就有问题了。我记得在一个项目中我们使用了C宏+方法和类的表用于将“指针”转换为函数以实现对函数的实际调用。一般的想法是在一些全局表中用宏“注册”类的实例,然后通过该表使用附加的调度来调用类的方法。