我们有一个基类ByteCode,这个基类是泛型的。ByteCode的子级需要编写以下形式的方法:
void m();
ByteCode类应该有一个方法定义:
typedef void (ByteCode::*Method)();
为了执行字节码,我们需要:
void exec() {
while (true) {
uint16_t opcode = getOpcode();
Method m = opcodes[opcode];
this->*m();
}
}
在一个类中做这件事是没有问题的。但是我们在基类中有泛型代码,派生类有数组:
class MyByteCodeEngine : public ByteCode {
private:
static Method opcodes[65536];
void m1() {}
void m2() {}
void m3() {}
};
Method MyByteCodeEngine ::opcodes[65536] = {
MyByteCodeEngine::m1,
MyByteCodeEngine::m2,
MyByteCodeEngine::m3
}
问题是这些方法不是基类,它们是派生的。但我们唯一的实例是派生的,我们不想产生虚拟的开销,我们只想强制转换并使其工作,但编译器正在捕捉每一个技巧。如果它相信我们的话:
Method MyByteCodeEngine ::opcodes[65536] = {
(Method)MyByteCodeEngine::m1,
(Method)MyByteCodeEngine::m2,
(Method)MyByteCodeEngine::m3
}
我们可以通过删除ByteCode类来解决这个问题,但这会迫使我们在有字节码解释器的任何时候重复代码。对于如何欺骗C++干净利落地接受这个问题,有什么建议吗?
发布于 2019-05-24 00:14:40
您可以使用Curiously recurring template pattern,以便基类知道成员函数的类型。
template<class T>
struct ByteCode {
typedef void (T::* Method)();
void exec() {
while (true) {
uint16_t opcode = getOpcode();
Method m = T::opcodes[opcode];
static_cast<T*>(this)->*m();
}
}
};
class MyByteCodeEngine : public ByteCode<MyByteCodeEngine > {
private:
static Method opcodes[65536];
void m1() {}
void m2() {}
void m3() {}
};
MyByteCodeEngine::Method MyByteCodeEngine ::opcodes[65536] = {
&MyByteCodeEngine::m1,
&MyByteCodeEngine::m2,
&MyByteCodeEngine::m3
}
https://stackoverflow.com/questions/56279030
复制相似问题