C++中‘auto变量未推导就使用’问题的解决方法探索
运行时动态包装无类型目标函数的实现问题
需求背景
我需要创建包装函数来修改现有目标函数,这些目标函数在运行时以无类型void*指针形式确定,各自的参数与返回类型均不相同。包装函数必须匹配目标函数的签名,以供外部代码调用。
现有基础实现方案
该方案可行,但存在丑陋的类型转换,且需要手动保持目标函数指针与包装函数的签名一致:
bool wrap(void* f, void** t) { *t = magic(); // 目标函数在运行时以void*形式确定 return true; } // 定义包装函数和目标函数指针存储变量 int(*foo_target)(int); int foo(int data) { return foo_target(data) + 10; } auto res = wrap(reinterpret_cast<void*>(&foo), reinterpret_cast<void**>(&foo_target));
其中wrap是负责核心逻辑的占位函数,针对每个目标函数,都需要手动定义包装函数(如foo)以及对应类型的目标函数指针变量(如foo_target)。
期望的优雅方案(存在编译错误)
我希望将类型转换隐藏在内部,且仅需定义一次函数签名,但该方案无法运行——lambda表达式中无法以这种方式使用foo变量:
template <class F> struct wrap { F* target; wrap(F&& f) { target = reinterpret_cast<F*>(magic()); } }; static auto foo = wrap( [](int data) -> int // <- 包装函数与目标函数的签名 { return foo.target(data) + 10; // 错误:无法在lambda中引用未完全初始化的foo // return 10; // 此语句可正常运行 });
公共基类方案(可行但仍有缺陷)
使用公共基类可以让方案生效,但每个包装函数中都需要手动添加类型转换,且函数签名需要重复定义两次:
struct wrap_base { void* target; }; template <class F> struct wrap : wrap_base { wrap(F&& f) { target = magic(); } }; static wrap_base foo = wrap( [](int data) -> int // <- 包装函数与目标函数的签名 { using func = int(int); // <- 此处重复定义了函数签名 return reinterpret_cast<func*>(foo.target)(data) + 10; });
补充说明
目标函数可能具有不同的调用约定,这意味着我可能无法使用无捕获lambda,不过目前尚未遇到相关问题。
内容的提问来源于stack exchange,提问作者dliw
相关产品推荐
相关产品推荐

