在 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);
以上是如何在 C 的映射中儲存具有不同簽名的函數?的詳細內容。更多資訊請關注PHP中文網其他相關文章!