C++20中如何基于输入类型返回函数指针并通过[]操作符调用
问题分析
你的现有代码存在几个关键问题:
- 运行时
if判断完全可以通过C++20的constexpr if在编译期完成分支选择,避免无效代码编译; - 传入函数名(如
malloc)时,虽然会自动退化为函数指针,但返回0的处理不安全,应该用编译期断言明确提示错误; - 扩展性差,新增函数时需要手动添加大量
if分支。
以下是基于C++20的优化方案,同时支持你要求的functions[malloc](0x123)调用方式,以及灵活扩展/修改返回类型的需求。
方案一:constexpr if 优化版(明确分支)
这个方案保留了直观的分支判断,用编译期逻辑替代运行时判断,同时添加安全检查:
#include <cstdlib> #include <iostream> #include <type_traits> class DelayedFunctions { decltype(&malloc) malloc_ptr; decltype(&free) free_ptr; public: // 构造函数:初始化存储的函数指针(示例用系统默认函数,实际可替换为自定义地址) constexpr DelayedFunctions() : malloc_ptr(::malloc), free_ptr(::free) {} template<typename T> constexpr T operator[](T) const noexcept { if constexpr (std::is_same_v<T, decltype(&malloc)>) { return malloc_ptr; } else if constexpr (std::is_same_v<T, decltype(&free)>) { return free_ptr; } else { // 编译期报错,直接提示不支持的函数类型 static_assert(!std::is_same_v<T, T>, "This function type is not supported by DelayedFunctions"); return nullptr; // 永远不会执行到这里 } } }; int main() { DelayedFunctions funcs; void* buf = funcs[malloc](0x100); // 直接用函数名,自动退化为指针 std::cout << "Allocated buffer: " << buf << '\n'; funcs[free](buf); return 0; }
方案二:std::tuple 存储(高扩展性)
如果需要支持大量函数,用元组存储函数指针,借助std::get实现编译期类型查找,无需手动写分支:
#include <cstdlib> #include <iostream> #include <type_traits> #include <tuple> class DelayedFunctions { // 用元组存储所有支持的函数指针,新增函数只需扩展元组即可 std::tuple<decltype(&malloc), decltype(&free)> func_tuple; public: constexpr DelayedFunctions() : func_tuple(::malloc, ::free) {} template<typename T> constexpr T operator[](T) const noexcept { // 通过类型直接从元组中获取对应函数指针 return std::get<T>(func_tuple); } }; int main() { DelayedFunctions funcs; void* buf = funcs[malloc](0x200); // 支持直接写函数名或&malloc std::cout << "Allocated buffer: " << buf << '\n'; funcs[free](buf); return 0; }
扩展:修改返回类型
如果你需要调整存储函数的返回类型(比如把malloc的void*改为int*),可以通过static_cast配合模板返回类型实现:
template<typename T> constexpr auto operator[](T) const noexcept { if constexpr (std::is_same_v<T, decltype(&malloc)>) { // 将void*(*)(size_t)转换为int*(*)(size_t) return static_cast<int*(*)(size_t)>(malloc_ptr); } else if constexpr (std::is_same_v<T, decltype(&free)>) { return free_ptr; } else { static_assert(!std::is_same_v<T, T>, "Unsupported function type"); return nullptr; } }
此时调用funcs[malloc](0x100)会返回int*类型的函数指针,调用后直接得到int*结果。
内容的提问来源于stack exchange,提问作者Arush Agarampur
相关产品推荐
相关产品推荐

