c++ - 函数指针迭代器上的非法操作数错误
问题描述
我收到以下错误:
- '<': 非法,左操作数的类型为 'const_Ty'
- '>: 非法,右操作数的类型为 'const_Ty'
在下面的代码中。
它是函数指针映射上的一个相对简单的迭代器,其中函数的形式为void (Game::*)(UINT)
。我根据浮点数检查该值,然后运行该函数。问题似乎已经存在for
,尽管我在其他地方有另一个基本相似的 for 循环,它可以正常工作。
using FuncPtr = void (Game::*)(UINT);
std::map<FuncPtr, float> funcDelayedTriggerMap;
void Game::PollProcessDelayedTriggers()
{
for (std::map<FuncPtr, float>::iterator it = funcDelayedTriggerMap.begin(); it != funcDelayedTriggerMap.end(); ++it)
{
float currentS = m_timer.GetElapsedSeconds();
if (it->second < currentS)
{
(this->*(it->first))(UINT_MAX);
funcDelayedTriggerMap.erase(it->first);
}
}
}
解决方案
成员函数指针不实现 operator<,这是默认排序函数std::map
使用的。
成员函数指针仅实现 operator== 和 operator!= 。
解决此问题的一种简单方法是使用单独的键并将函数指针放入映射的值中,例如:
std::map<int, std::pair<FuncPtr, float>>
或者,如果您不需要快速查找std::map
,也可以使用简单的向量:
std::vector<std::pair<FuncPtr, float>>
另一种方法是使用函数指针类型作为键:
using FuncPtr = void (Game::*)(int);
// Just a helper to get a unique type for each function pointer
template<FuncPtr ptr>
struct Tag {};
struct DelayedTrigger {
FuncPtr ptr;
float value;
DelayedTrigger() : ptr(nullptr), value(0.0f) {}
DelayedTrigger(FuncPtr _ptr, float _value) : ptr(_ptr), value(_value) {}
};
std::map<std::type_index, DelayedTrigger> funcDelayedTriggerMap;
void Game::PollProcessDelayedTriggers()
{
for (std::map<std::type_index, DelayedTrigger>::iterator it = funcDelayedTriggerMap.begin(); it != funcDelayedTriggerMap.end(); ++it)
{
float currentS = 1.0;
if (it->second.value < currentS)
{
(this->*(it->second.ptr))(0);
funcDelayedTriggerMap.erase(it->first);
}
}
}
这实质上是使用特定的函数指针作为唯一键。
然后,您可以像这样添加新条目:
funcDelayedTriggerMap.emplace(typeid(Tag<&Game::DoIt>), DelayedTrigger{&Game::DoIt, 1.0f});
// or
funcDelayedTriggerMap[typeid(Tag<&Game::DoIt>)] = {&Game::DoIt, 1.0f};
并检查是否存在函数:
if(funcDelayedTriggerMap.contains(typeid(Tag<&Game::DoIt>))) {
// ...
}
但是,这仅在您知道要在编译时与地图一起使用的所有功能时才有效。
推荐阅读
- docker - 如何更改现有的 docker 容器选项
- go - Go中的可选参数?
- python - Python调度一个函数
- r - 无法将新库路径添加到 .libPaths()
- python - 如何通过计算像素来计算距离
- jenkins - 在 HTTP POST 标头中添加有效的 crumb,但仍然出现 403 错误
- ios - 修复实时取景问题
- firebase - Firebase 登录身份验证失败并使用正确的凭据
- ios - React-Native:如何为动态链接的一个构建添加多个 google-service-info plist 文件?
- oracle - 如何使用循环将数据记录插入表中?