【发布时间】:2020-08-25 19:35:00
【问题描述】:
假设我有应用程序中函数的运行时内存地址并且我知道所述函数的返回类型,是否可以使用可变参数模板调用函数,知道函数的返回类型、参数和调用约定?
模板化函数必须同时支持 void 和非 void 返回类型。由于我们正在处理函数指针,编译器不应该抱怨,尽管返回 ptr。
我想过做这样的事情:
template<typename ReturnType, typename Address, typename... Args>
ReturnType function_caller(Address address, Args... args)
{
ReturnType(*ptr)(Args...) = address;
return ptr(args...);
}
int main()
{
auto address = 0x100;
auto address2 = 0x200;
function_caller<void>(&address, 1, 1); // Function with return type void.
int result = function_caller<int>(&address2, 1, 2, 3.f, "hello");
// result should contain the int value we received by calling the function at 0x200
}
遗憾的是编译器抛出错误 C2440:它无法将地址“address”转换为“ReturnType (__cdecl *)(int,int)”
非常感谢您对这个问题的帮助。我知道我可以将这个包装器拆分为 2 个函数:一个用于 void 调用,一个用于非 void 调用,但我希望有一个更优雅、支持模板的解决方案。
谢谢你,祝你有美好的一天!
【问题讨论】:
-
是的,我知道,地址不是真实地址,只是为了展示概念。这不是我将在运行时使用的代码。请假设地址是正确的。除此之外,编译器不会介意,因为这是运行时错误,而不是编译时间
-
自动扣除参数也很危险。第四个参数是
const char*还是const char[6]?我很确定是后者。 -
如果你愿意为 void 调用使用奇怪的语法,你也可以哄它来推断返回类型。 coliru.stacked-crooked.com/a/42c1c60bf0e2f50a
标签: c++ templates variadic-templates