调用成员函数指针时指向与对象不兼容的成员类型指针
Pointer to member type incompatible with object when calling member function pointer
问题
我有一个在 运行 时分配的成员函数指针数组。尝试调用它们时出现编译时错误:
pointer to member type 'void (YCPU::)(uint16_t)' {aka 'void (YCPU::)(short unsigned int)'} incompatible with object type 'YCPUInstruction'`
我无法理解调用指针的正确语法。
代码和问题详情
我有一个存储两个成员函数指针的结构YCPUInstruction
。这些函数指针指向YCPU
内部的成员函数。我存储了一个 YCPUInstructions
的数组,在初始化期间我调用了 initialize,它将这些指针分配给正确的成员函数。
成员函数指针和YCPU指令:
typedef void (YCPU::*YCPUOpcode)(uint16_t opcode);
typedef std::string (YCPU::*YCPUDisassembler)(std::string name, uint16_t operand, uint16_t nextword, uint16_t address,
bool show_memory_contents, uint16_t &instruction_size);
struct YCPUInstruction {
std::string name;
static YCPUOpcode opcode;
static YCPUDisassembler disassembler;
int cycles;
bool is_nop;
void initialize(std::string name, YCPUOpcode opcode, YCPUDisassembler disassembler, int cycles, bool is_NOP = false)
{
this->name = name;
this->opcode = opcode;
this->disassembler = disassembler;
this->cycles = cycles;
this->is_nop = is_NOP;
}
};
YCPU
class YCPU
{
public:
// YCPUOpcode points to one these functions (many more than these 3, just examples)
void NOP(uint16_t opcode);
void ADC(uint16_t opcode);
void ADD(uint16_t opcode);
...
// YCPUDisassembler points to one of these functions (many more than these 2, just examples)
std::string disassemble_ALU(std::string name, uint16_t operand, uint16_t nextword, uint16_t address,
bool show_memory_contents, uint16_t &instruction_size);
std::string disassemble_BRA(std::string name, uint16_t operand, uint16_t nextword, uint16_t address,
bool show_memory_contents, uint16_t &instruction_size);
...
private:
std::array<YCPUInstruction, 256> opcodes;
};
在设置过程中,我像这样初始化操作码:
void YCPU::initialize_opcodes()
{
opcodes[0x01].initialize("CMP", &YCPU::CMP, &YCPU::disassemble_ALU, 0);
opcodes[0x02].initialize("CMP", &YCPU::CMP, &YCPU::disassemble_ALU, 0);
opcodes[0x03].initialize("CMP", &YCPU::CMP, &YCPU::disassemble_ALU, 0);
... // and so on for all instructions
}
初始化后,我尝试这样调用成员函数:
void YCPU::run_one_instruction()
{
...
uint16_t word = read_mem_int16(PC, SI_CS); // 0x1-0xff
YCPUInstruction op = opcodes[word & 0xFFFF];
(op.*YCPUInstruction::opcode)(word);
...
}
但是,这会引发我上面提到的编译器错误。
如果我首先取消引用 op
,就像这样:
(op->*YCPUInstruction::opcode)(word);
我收到这个错误:
error: no match for 'operator->*' (operand types are 'YCPUInstruction' and 'YCPUOpcode' {aka 'void (YCPU::*)(short unsigned int)'})
如果我将语法更改为:
(op->*opcode)(word);
或:
(op.*opcode)(word)
我收到这个错误
error: 'opcode' was not declared in this scope
调用这些成员函数指针需要使用什么具体语法?
.*
的左操作数必须引用/->*
的左操作数必须指向包含class的成员函数的对象。右操作数可以是给出指向成员值的指针的任何表达式。
您正在使用的成员函数中包含 class 的是 YCPU
,因此将 YCPUInstruction
作为左操作数是不正确的。我看到你的表达式在 YCPU
的另一个成员函数中,所以假设你想使用 *this
作为调用函数的 YCPU
,你想要 this->*
。下面的表达式可以是普通的 .
或 ->
表达式,只是获取而不是调用 YCPUInstruction
中指向成员函数值的指针。由于 .*
和 ->*
的优先级很奇怪,因此通常需要并始终建议使用过多的括号。
void YCPU::run_one_instruction()
{
// ...
uint16_t word = read_mem_int16(PC, SI_CS); // 0x1-0xff
YCPUInstruction op = opcodes[word & 0xFFFF];
(this->*(op.opcode))(word);
// ...
}
问题
我有一个在 运行 时分配的成员函数指针数组。尝试调用它们时出现编译时错误:
pointer to member type 'void (YCPU::)(uint16_t)' {aka 'void (YCPU::)(short unsigned int)'} incompatible with object type 'YCPUInstruction'`
我无法理解调用指针的正确语法。
代码和问题详情
我有一个存储两个成员函数指针的结构YCPUInstruction
。这些函数指针指向YCPU
内部的成员函数。我存储了一个 YCPUInstructions
的数组,在初始化期间我调用了 initialize,它将这些指针分配给正确的成员函数。
成员函数指针和YCPU指令:
typedef void (YCPU::*YCPUOpcode)(uint16_t opcode);
typedef std::string (YCPU::*YCPUDisassembler)(std::string name, uint16_t operand, uint16_t nextword, uint16_t address,
bool show_memory_contents, uint16_t &instruction_size);
struct YCPUInstruction {
std::string name;
static YCPUOpcode opcode;
static YCPUDisassembler disassembler;
int cycles;
bool is_nop;
void initialize(std::string name, YCPUOpcode opcode, YCPUDisassembler disassembler, int cycles, bool is_NOP = false)
{
this->name = name;
this->opcode = opcode;
this->disassembler = disassembler;
this->cycles = cycles;
this->is_nop = is_NOP;
}
};
YCPU
class YCPU
{
public:
// YCPUOpcode points to one these functions (many more than these 3, just examples)
void NOP(uint16_t opcode);
void ADC(uint16_t opcode);
void ADD(uint16_t opcode);
...
// YCPUDisassembler points to one of these functions (many more than these 2, just examples)
std::string disassemble_ALU(std::string name, uint16_t operand, uint16_t nextword, uint16_t address,
bool show_memory_contents, uint16_t &instruction_size);
std::string disassemble_BRA(std::string name, uint16_t operand, uint16_t nextword, uint16_t address,
bool show_memory_contents, uint16_t &instruction_size);
...
private:
std::array<YCPUInstruction, 256> opcodes;
};
在设置过程中,我像这样初始化操作码:
void YCPU::initialize_opcodes()
{
opcodes[0x01].initialize("CMP", &YCPU::CMP, &YCPU::disassemble_ALU, 0);
opcodes[0x02].initialize("CMP", &YCPU::CMP, &YCPU::disassemble_ALU, 0);
opcodes[0x03].initialize("CMP", &YCPU::CMP, &YCPU::disassemble_ALU, 0);
... // and so on for all instructions
}
初始化后,我尝试这样调用成员函数:
void YCPU::run_one_instruction()
{
...
uint16_t word = read_mem_int16(PC, SI_CS); // 0x1-0xff
YCPUInstruction op = opcodes[word & 0xFFFF];
(op.*YCPUInstruction::opcode)(word);
...
}
但是,这会引发我上面提到的编译器错误。
如果我首先取消引用 op
,就像这样:
(op->*YCPUInstruction::opcode)(word);
我收到这个错误:
error: no match for 'operator->*' (operand types are 'YCPUInstruction' and 'YCPUOpcode' {aka 'void (YCPU::*)(short unsigned int)'})
如果我将语法更改为:
(op->*opcode)(word);
或:
(op.*opcode)(word)
我收到这个错误
error: 'opcode' was not declared in this scope
调用这些成员函数指针需要使用什么具体语法?
.*
的左操作数必须引用/->*
的左操作数必须指向包含class的成员函数的对象。右操作数可以是给出指向成员值的指针的任何表达式。
您正在使用的成员函数中包含 class 的是 YCPU
,因此将 YCPUInstruction
作为左操作数是不正确的。我看到你的表达式在 YCPU
的另一个成员函数中,所以假设你想使用 *this
作为调用函数的 YCPU
,你想要 this->*
。下面的表达式可以是普通的 .
或 ->
表达式,只是获取而不是调用 YCPUInstruction
中指向成员函数值的指针。由于 .*
和 ->*
的优先级很奇怪,因此通常需要并始终建议使用过多的括号。
void YCPU::run_one_instruction()
{
// ...
uint16_t word = read_mem_int16(PC, SI_CS); // 0x1-0xff
YCPUInstruction op = opcodes[word & 0xFFFF];
(this->*(op.opcode))(word);
// ...
}