我目前正在编写一个用于练习C ++的gameboy模拟器。我已经到了实现CPU指令的部分,并确定了std :: function的向量是一个不错的选择。
请注意:u8
是uint8_t
的别名。
在我的代码中,有一个std::function<u8()>
向量,有三种类型的成员:
u8
的lambda表达式。我最初尝试使用initalizer列表,但它没有用。我后来发现这是因为我需要在指针上调用std::bind(/*function ptr*/, this);
,但是当在模板化函数指针上调用它时,我得到以下错误:no matching function for call to 'bind'
。我想有一个初始化列表,因为现在它是一个连续调用emplace_back
的函数。
这是错误行:
instruction_set.emplace_back(bind(&CPU::OPLoadDualRegister8<B, B>, this)); // 0x40 LD B, B
有趣的是,当B
被文字(例如0x00
)取代时,它的效果非常好。 B
是u8
,这是模板接受的内容。
所以:
std::bind
来解决它们(所有参数都是u8
或u8&
,那会更好。谢谢,扎克。
答案 0 :(得分:0)
好的,你的问题和评论之间有很多关系。以下是我发现的一些事情:
如果您要索引一个矢量来解码操作码,您可能不应该按顺序将emplace_back插入到矢量中。而是将向量增长到最终大小,用空值填充它,并使用下标运算符将函数放入。instruction_set[0x40] = ...
使用switch
语句并直接调用函数可能是更好的选择。显然,不知道你项目的细节,所以这可能是不可能的。
当您说B
为u8
时,您的意思是B
是u8
类型的变量吗?普通的变量不能用于实例化模板。 B
必须是调用函数constexpr
变量或static const
上的宏模板参数(在编译时基本上已知)。
std::bind
对任何人来说都没有任何乐趣,所以你并不孤单。我不认为这是你问题的根本原因,但你应该更喜欢使用捕捉lambdas来绑定东西。
有趣的是,去年C ++的新心形电影师Matt Godbolt(Compiler Explorer的作者)给了talk on emulating a 6502 in JavaScript。它不完全是关于这个主题的权威参考,但如果你对模拟旧的微处理器感兴趣,可能值得一看。