【问题标题】:Function that returns a cast enumerated value C++返回强制转换枚举值 C++ 的函数
【发布时间】:2013-11-06 17:01:59
【问题描述】:

我正在尝试使用传感器位置的枚举值创建一个类,并且我正在使用具有 int 类型的向量作为此函数的输入,并且我想要一个枚举值。我不确定这段代码是否有效。我不太确定如何测试它。

#include <vector>

place getPos(vector<int>& pin)
    {
        int i;
    for(i = 0; i <= sizeof(pin); i++)
    {
    if (pin[i])
        break;
    }

    place castEnum = (place)i;
    return castEnum;

    }

所以这是我能收集到的更新:

#include <vector>

place getPos(vector<int>& pin)
{
    int i;
    for(i = 0; i <= pin.size(); i++)
    {
        if (pin[i])
            break;
    }
    return static_cast <place> (i);

}

【问题讨论】:

  • 您可以编写一些测试用例,看看它是否会产生您期望的结果。我至少可以看到一个问题。
  • sizeof(pin) 不会像你想的那样做。
  • 如果你不确定如何测试它,你就不确定它应该如何工作。首先澄清这一点,然后运行它以验证它确实做到了。
  • 另一个重要问题是在枚举中根本没有定义的强制转换值。无论如何,这种 C 风格的转换在 C++ 程序中没有任何作用。这实际上是一个 XY 问题,他的实际问题是 X,但是您已经确定解决方案中的问题 Y 是需要解决的问题。
  • 我认为您使用向量作为 const 大小数组。考虑使用std::array&lt;int,ARRAY_SIZE&gt; 并将数组大小定义为宏。

标签: c++ function class vector enums


【解决方案1】:

可以使用static_cast 将整数值转换为enum

enum FooType
{
  ftOne = 1,
  ftTwo
};

int main()
{
  const int n = 1;
  FooType ft = static_cast <FooType> (n);
}

由于static_cast 是编译时操作,而n 仅在运行时已知,如果n 与枚举值之一不匹配,则结果值未指定。这可能是一个严重的问题。

您需要事先确定您要转换的值是该enum 的合法值。当您考虑到这一点时,通常这会破坏首先进行演员表的目的。

这通常表明您做错了什么。为什么需要将整数值转换为enum?一个可能的原因是因为您从套接字中提取了该值,或者从其他一些进程间通信方式中获取了该值。除此之外,不会立即想到其他有效的用例。这是XY Problem 的经典指示。

【讨论】:

  • "如果 n 与枚举值之一不匹配,则结果值未指定" 这是一个轻微的简化;如果结果值不在枚举数的范围内,则未指定结果值。如果底层类型是固定的,则此类型定义范围;否则,范围为 [0, 2^N] 对于正枚举数,其中 N 基于最小和最大枚举数值。
  • @DyP:您是否建议为enum { foo_a = 1, foo_b = 3 }; 指定static_cast&lt;foo&gt;(2)
  • 我想是的;至少我调查了这件事some time ago,在我看来,当时的定义很明确。
  • @DyP:这对我来说似乎很奇怪。感谢您的澄清。
【解决方案2】:

只是解决显而易见的问题:

#include <vector>

place getPos(vector<int>& pin)
{
    int i;
    // sizeof(pin) is a constant representing the size of a vector type
    // Edit: missed that for(i = 0; i <= pin.size(); i++)
    for(i = 0; i < pin.size(); ++i)
    {
        if (pin[i])
            break;
    }
    return place(i);
}

不太明显:

You may replace your vector with a std::bitset (or an unsigned integer)
representing the flags in your enum.

【讨论】:

    【解决方案3】:

    解决错误和逻辑问题:

    #include <vector>
    
    place getPos(vector<int>& pin)
    {
        int i;
        for(i = 0; i < pin.size(); i++)
       //            ^ Needs to be <, not <=
       //              ^^^^^^^^^^ Needs to be pins.size(), not sizeof(pins) 
        {
            if (pin[i])
                break;
        }
    
        // alternatively,
        //int i = std::find_if(pins.begin(), pins.end(), [](int a)
        //{
        //    return a != 0;
        //});
    
        place castEnum = DEFAULT_ENUM_VALUE; // whatever you want for a default enum value
        switch (i)
        {
        case ENUM_VALUE_1:
            castEnum = ENUM_VALUE_1;
            break;
        case ENUM_VALUE_2:
            castEnum = ENUM_VALUE_2;
            break;
        // etc.
        }
        return castEnum;
    }
    

    使用 switch 语句可以避免尝试强制转换对您的枚举无效的值。您需要将枚举值(例如INVALID_ENUM = -1)定义为默认值。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多