C では、異なるシグネチャを持つ関数をデータ構造に保存する必要があるシナリオが発生することがあります。文字列キーとジェネリック メソッドを値として受け入れるマップ コンテナーがあるとします。これを可能にするために、次のアプローチを検討してください。
C は、型消去用の std::any 型を提供します。 std::any を使用すると、正確な型を指定せずに関数ポインターまたはラムダ式をコンテナーに格納できます。ただし、ストアド関数を呼び出すには、ストアド関数を正しい型に明示的にキャストする必要があります。
明示的なキャストを克服するには、テンプレート演算子 Operator( ) 格納された std::any オブジェクトをパラメータとして受け取るカスタム ラッパー クラス。この演算子を使用すると、明示的なキャストを必要とせずにストアド関数を呼び出すことができます。
このようなラッパー クラスの実装例を次に示します。
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この実装では、AnyCallable クラスは格納された std::any オブジェクトをラップし、指定された関数を呼び出す Operator() を提供します。引数。
AnyCallable クラスを使用すると、異なるシグネチャを持つ関数を格納するマップを作成し、それらを動的に呼び出すことができます。
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);
型消去方法でストアド関数を呼び出す場合は、正しい引数の型を明示的に渡す必要があることに注意してください。型の不一致により、std::bad_any_cast 例外が発生します。
以上が異なるシグネチャを持つ関数を C のマップに保存するにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。