首頁 >後端開發 >C++ >如何在 C 的映射中儲存具有不同簽名的函數?

如何在 C 的映射中儲存具有不同簽名的函數?

Patricia Arquette
Patricia Arquette原創
2024-11-13 12:32:02700瀏覽

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

在映射中儲存具有不同簽章的函數

在 C 中,您可能會遇到需要在資料結構中儲存具有不同簽章的函數的情況。假設您有一個接受字串鍵和通用方法作為其值的映射容器。為了實現這一點,請考慮以下方法:

類型擦除和任何類型

C 提供了 std::any 類型用於類型擦除。您可以使用 std::any 將函數指標或 lambda 表達式儲存在容器中,而無需指定其確切類型。但是,要呼叫儲存的函數,您需要將其明確轉換為正確的類型。

函數呼叫的運算子重載

要克服明確轉換,您可以定義一個模板運算子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中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn