【发布时间】:2023-01-02 03:07:49
【问题描述】:
我想设计一个功能。此函数将采用 2 个参数。第一个参数将是包含函数名称的枚举类对象,第二个参数将是可变的。在我要设计的这个函数中,我希望使用来自可变参数的参数调用该函数,无论哪个函数名称来自枚举类对象。
这些被调用函数的签名彼此完全不同。无论被调用函数返回什么值,它都应该在我将要编写的函数中返回该值。这个return语句可以是类类型,也可以是double、long等基本类型。
结果,我希望能够按如下方式使用此功能。
enum class FunctionNames {
func1,
func2,
};
Myclass func1(int a, int b);
double func2();
int main() {
auto res1 = call_function(FunctionNames::func1, 10, 20);
auto res2 = call_function(FunctionNames::func2);
}
我试过 std::invoke。 std::invoke 将参数作为函数指针。实际上我可以使用 std::invoke。注意:我的编译器版本是C++17。
我想要一个像下面代码一样的功能。但是这样它会给出语法错误。
template <typename... Args>
auto myFunction(FunctionNames functionName, Args... args) {
switch(functionName) {
case FunctionNames::func1:
return std::invoke(func1, std::forward<Args>(args)...);
case FunctionNames::func2:
return std::invoke(func2, std::forward<Args>(args)...);
// Add more cases here for each function you want to call
}
return result;
}
【问题讨论】:
-
请复制并粘贴该语法错误
-
我没有费心去测试它,但也许
if constexpr (functionName == FunctionNames::func1) return func1(std::forward<Args>(args)...); [else] if ...etc.... -
你到底想通过这种方式达到什么目的?它对我来说似乎没有意义:如果您已经知道枚举值,那么您就知道要调用的函数,因此可以直接调用它。如果您不知道实际调用哪个函数,那么您如何知道要使用哪些参数?
-
如果没有允许在编译时做出决定的常量表达式,这是不可能的,因此您不能根据传递的参数值返回不同的东西;您唯一的选择是返回类似
std::variant<...>的内容。此外,std::forward只有在您实际使用转发引用时才有意义,而您在这里没有这样做。 -
从根本上说,C++ 不是这样工作的。这是一个 XY 问题。你应该解释你试图解决的真正问题。不,这不是关于编写这种模板函数的问题,而是您认为解决方案是编写这种模板函数的问题。
标签: c++ templates c++17 variadic-templates typetraits