c++ 14 个可变参数模板,用于使用枚举调用不同方法

问题描述 投票:0回答:2

我想要有2个方法,一个是SetVariable,另一个是MyClass中的GetVariable 两者都将接收一个枚举和参数,参数可以不止一种,也可以不止一种类型 并根据枚举调用相关的私有方法 我想从另一个名为 OtherClass 的类中调用这些方法 (这些不是真实姓名,只是为了解释) 我与 ChatGPT 进行三合一,它告诉我有关可变模板的信息,但问题是我得到了错误的参数编号错误

template <typename... Args>
    bool SetVariable(const int& variable, Args&&... args)
    {
        auto returnValue = false;
        switch (variable)
        {
        case 1:
        {
            returnValue = Function1(std::forward<Args>(args)...);
            break;
        }
        case 2:
        {
            returnValue = Function2(std::forward<Args>(args)...);
            break;
        }

        default:
            break;
        }

        return returnValue;
    }

这既是函数 1 又是函数 2:

Function1( const int & axis_, const double& velocity_ )
Function2( std::vector<int>& chameleonFirmwareVec_ )

这就是我从不同的类调用 SetVariable 的方式

bool Core::OtherClass::Function1Call( const int & axis_, const double& velocity_ )
{
    return MyClass.SetVariable(1, axis_, velocity_);
}

这里的错误是 Function2':函数不接受 2 个参数 而且我根本不会调用它,如果我有不止一种情况错误安培

c++ c++14 variadic-templates
2个回答
0
投票

但问题是我得到了错误的参数编号错误

问题在于,所示

switch
中任何分支内的代码都必须有效,无论该分支代码是否被执行。

如果可以在编译时决定选择哪个分支,则可以使用

constexpr if


0
投票

问题是这里的枚举值(

variable
)是在运行时确定的,而参数的类型(
Args
)是在编译时确定的。

因此,当调用

SetVariable(1, axis_, velocity_)
时,编译器会生成一个函数
SetVariable(int, double)
的模板实例化,而这个函数包含对
Function2(int, double)
的调用,而该函数并不存在。这会导致编译错误。

避免这种情况的两种方法是使参数类型也由运行时确定,或者使枚举编译时确定。


要使参数的类型由运行时确定,一种方法是这样设置:

using AxisVelocity = std::pair<int, double>;
void SetVariable(
   int variable,
   const std::variant<
       AxisVelocity,
       std::vector<int>
   >& value
) {
   if(variable == 1) {
      AxisVelocity axisVelocity = std::get<1>(value);
      Function1(axisVelocity.first, axisVelocity.second);
   } else if(variable == 2) {
      Function2(std::get<0>(value));
   }
}

SetVariable(1, AxisVelocity(axis, velocity));

像这样,如果类型与参数不匹配,它会在运行时抛出异常(来自

std::get
)。

这当然可以进一步细化,例如通过围绕

std::variant
制作一个包装类型,它也可以在相似类型之间进行隐式转换,或者具有转发到
SetVariable(variable, Args...)
的可变参数
SetVariable(variable, std::tuple<Args...>)
等。


另一种解决方案是使枚举

variable
也在编译时确定,例如:

template<int Variable, class... Args>
void SetVariable(Args&&... args) {
    if constexpr(Variable == 1) {
        Function1(args...);
    } else if constexpr(Variable == 2) {
        Function2(args...);
    }
}

SetVariable<1>(axis, velocity);

if constexpr
确保未采用的分支(取决于编译时
Variable
)不会被编译,因此不需要
Function2(int, double)
存在。

但在这种情况下,为不同的枚举设置不同的函数可能会更好。

© www.soinside.com 2019 - 2024. All rights reserved.