Dalam C , anda boleh menghadapi senario di mana anda perlu menyimpan fungsi dengan tandatangan berbeza dalam struktur data. Katakan anda mempunyai bekas peta yang menerima kunci rentetan dan kaedah generik sebagai nilainya. Untuk menjadikannya mungkin, pertimbangkan pendekatan berikut:
C menyediakan std::sebarang jenis untuk jenis pemadaman. Anda boleh menggunakan std::any untuk menyimpan penunjuk fungsi atau ungkapan lambda dalam bekas tanpa menyatakan jenis tepatnya. Walau bagaimanapun, untuk menggunakan fungsi yang disimpan, anda perlu menghantarnya ke jenis yang betul secara eksplisit.
Untuk mengatasi penghantaran eksplisit, anda boleh menentukan operator operator templat( ) pada kelas pembalut tersuai yang mengambil std::any object yang disimpan sebagai parameter. Operator ini membenarkan anda menggunakan fungsi tersimpan tanpa memerlukan penghantaran eksplisit.
Berikut ialah contoh pelaksanaan kelas pembalut sedemikian:
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; };
Dalam pelaksanaan ini, kelas AnyCallable membungkus objek std::any object yang disimpan dan menyediakan operator() yang memanggil fungsi dengan argumen yang ditentukan.
Dengan kelas AnyCallable, anda boleh cipta peta yang menyimpan fungsi dengan tandatangan yang berbeza dan memanggilnya secara dinamik:
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);
Perhatikan bahawa apabila menggunakan fungsi yang disimpan dalam cara yang dipadamkan jenis, anda perlu lulus yang betul jenis hujah secara eksplisit. Jenis ketidakpadanan akan mengakibatkan pengecualian std::bad_any_cast.
Atas ialah kandungan terperinci Bagaimanakah saya boleh menyimpan fungsi dengan tandatangan yang berbeza dalam peta dalam C?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!