使用函数指针的 STL 映射
我开发了一个具有许多内置函数的脚本引擎,因此要调用任何函数,我的代码只是进入 if .. else if .. else if
墙检查名称,但我想制定更有效的解决方案。
我应该使用以字符串作为键、指针作为值的hashmap吗?我怎样才能使用STL图来做到这一点?
编辑: 我想到的另一点是:当然使用映射会强制编译器不要内联函数,但我的低效方法没有因函数调用的必要性而产生任何开销,它只是执行代码。
所以我想知道函数调用生成的开销是否会比使用 if..else
链更好。否则我可以通过在运行时检查字符来最小化比较次数(会更长)但更快)。
I developed a scripting engine that has many built-in functions, so to call any function, my code just went into an if .. else if .. else if
wall checking the name but I would like to develop a more efficient solution.
Should I use a hashmap with strings as keys and pointers as values? How could I do it by using an STL map?
EDIT:
Another point that came into my mind: of course using a map will force the compiler not to inline functions, but my inefficient approach didn't have any overhead generated by the necessity of function calls, it just executes code.
So I wonder if the overhead generated by the function call will be any better than having an if..else
chain.. otherwise I could minimize the number of comparisons by checking a character at runtime (will be longer but faster).
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
好吧,你可以使用
any_map
来存储具有不同签名的函数(但是调用它会很混乱),并且你可以使用int_map
来调用具有特定签名的函数(看起来更好) 。Well, you can use
any_map
to store functions with different signatures (but calling it will be messy) and you can useint_map
to call functions with a specific signature (looks nicer).我已成功修改 Mohit 的示例 以处理成员函数指针:
I've managed to modify the example from Mohit to work on member function pointers:
无论您的函数签名是什么:
请注意,
ScriptFunction
类型可以泛化为std::function
,这样您就可以支持任何可调用的东西,而不是只是函数指针。Whatever your function signatures are:
Note that the
ScriptFunction
type could be generalized tostd::function</* whatever*/>
so you can support any callable thing, not just exactly function pointers.在 C++11 中你可以这样做:
该接口只需要返回类型,它会处理调用方的所有其他事情。
In C++11 you can do something like this :
This Interface needs only the return type and it takes care of everything else from the caller side.
您还可以使用 Boost.Function 和 Boost.Bind 甚至允许您在某种程度上拥有 异构函数:
当然,它也可以是兼容原型的函数映射。
You can also use Boost.Function and Boost.Bind what even allows you, to some degree, to have map of heterogeneous functions:
It can be a map of functions of compatible prototypes as well, of course.
上面的答案似乎给出了完整的概述,这仅涉及您的第二个问题:
按键检索映射元素具有 O(log n) 复杂度。通过键检索哈希图的复杂度为 O(1) + 在发生冲突时需要一些额外的东西。因此,如果您的函数名称有一个好的哈希函数,请使用它。您的实施将有一个标准的实施。应该没问题。
但请注意,低于一百个元素的任何元素都不会带来太多好处。
哈希图的唯一缺点是冲突。在你的情况下,哈希图将是相对静态的。您知道您支持的函数名称。因此,我建议您创建一个简单的测试用例,在其中使用所有键调用 unordered_map<...>::hash_function 以确保没有任何冲突。之后,你就可以忘记它了。
快速谷歌搜索哈希函数的潜在改进让我到达那里:
一些好的哈希函数
也许,根据您的命名约定,您可以改进该函数的某些方面。
Above answers seem to give a complete overview, this regards only your second question:
Map element retrieval by key has O(log n) complexity. Hashmap retrieval by key has O(1) complexity + a little stuff on the side in case of collisions. So if theres a good hash function for your function names, use it. Your implementation will have a standard one. It should be fine.
But be aware, that anything below a hundred elements will not benefit all too much.
The only downside of a hash map is collision. In your case, the hashmap will be relatively static. You know the function names you support. So I advise you to create a simple test case, where you call unordered_map<...>::hash_function with all your keys to make sure that nothing collides. After that, you can forget about it.
A quick google for potential improvements on hash functions got me there:
A fiew good hash functions
Maybe, depending on your naming conventions, you can improve on some aspects of the function.