ホームページ >バックエンド開発 >C++ >異なるシグネチャを持つ関数を C のマップに保存するにはどうすればよいですか?

異なるシグネチャを持つ関数を C のマップに保存するにはどうすればよいですか?

Patricia Arquette
Patricia Arquetteオリジナル
2024-11-13 12:32:02729ブラウズ

How can I store functions with different signatures in a map in C  ?

マップに異なるシグネチャを持つ関数を保存する

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 サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。