In C++, you can encounter scenarios where you need to store functions with different signatures in a data structure. Suppose you have a map container that accepts a string key and a generic method as its value. To make this possible, consider the following approach:
C++ provides the std::any type for type erasure. You can use std::any to store a function pointer or a lambda expression in a container without specifying its exact type. However, to invoke the stored function, you need to cast it to the correct type explicitly.
To overcome the explicit casting, you can define a template operator operator() on a custom wrapper class that takes the stored std::any object as a parameter. This operator allows you to invoke the stored function without the need for explicit casting.
Here's an example implementation of such a wrapper class:
template<typename Ret> struct AnyCallable { AnyCallable() {} template<typename F> AnyCallable(F&& fun) : AnyCallable(std::function(std::forward<F>(fun))) {} template<typename ... Args> AnyCallable(std::function<Ret(Args...)> fun) : m_any(fun) {} template<typename ... Args> Ret operator()(Args&& ... args) { return std::invoke(std::any_cast<std::function<Ret(Args...)>>(m_any), std::forward<Args>(args)...); } std::any m_any; };
In this implementation, the AnyCallable class wraps the stored std::any object and provides an operator() that invokes the function with the specified arguments.
With the AnyCallable class, you can create a map that stores functions with different signatures and invoke them dynamically:
void foo(int x, int y) { /* ... */ } void bar(std::string x, int y, int z) { /* ... */ } std::map<std::string, AnyCallable<void>> map; map["foo"] = &foo; map["bar"] = &bar; map["foo"](1, 2); map["bar"]("Hello", 1, 2);
Note that when invoking the stored functions in a type-erased manner, you need to pass the correct argument types explicitly. Type mismatches will result in a std::bad_any_cast exception.
以上是如何在 C 的映射中存储具有不同签名的函数?的详细内容。更多信息请关注PHP中文网其他相关文章!