enum vs static consts

时间:2013-11-08 18:01:54

标签: c++ enums c++03

我目前正在考虑是否更喜欢名称空间的枚举或命名空间的静态组的问题。 什么应该是默认选择?为什么?

选项1:

namespace Direction
{
    enum Direction
    {
        north,
        east,
        south,
        west,
    };
}

选项2:

namespace Direction
{
    static const unsigned char north = 0;
    static const unsigned char east = 1;
    static const unsigned char south = 2;
    static const unsigned char west = 3;
}

两者各有利弊。

Pro enum:

  1. 某些类型的安全:

    void foo(Direction dir); // the compiler won't allow you to just pass an int or a value of an unrelated enum without explicitly casting it
    
  2. Contra enum:

    1. 类型安全性相当有限:

      enum A
      {
          Entry1 = 1
      };
      
      enum B
      {
          Entry2 = 10
      };
      
      A a;
      if(a == Entry2)
          ; // ouch!
      
    2. 不支持除int之外的任何其他类型 - 在C ++ 11之前,不能只有一个枚举,例如long long,short或char

    3. 枚举的命名空间不是最理想的

      1. 如果没有将枚举包装到单独的命名空间中,那么它的所有成员都会污染周围的命名空间。

      2. 如果将枚举包装到单独的命名空间中,那么当使用枚举本身作为类型时,会获得一些冗余: 然后必须以Direction :: Direction的方式声明方向变量(当不使用Direction :: Direction时),这将使它们再次污染外部命名空间(最后在代码的那部分,使用指令生效)),能够以Direction :: north而不仅仅是north的方式命名其成员

    4. Pro static const:

      1. 在C ++ 11之前的C ++中更好的类型支持 - 例如,可以使用类似无符号字符的常量
      2. 正确的范围 - 没有外部命名空间的污染,没有通过using指令明确要求(甚至只在有限的范围内)
      3. Contra static const:

        1. 比枚举更少的类型安全 - 一个不再能够声明这样的函数原型:

          void foo(Direction dir);
          

          但必须按以下方式进行:

          void foo(unsigned char dir); // now each variable of type unsigned char or of a type that can implicitly be casted into unsigned char can be passed, even if its totally unrelated to the expected "enumeration" or if the value does not match the value of any of the expected consts
          
        2. 修改 在这里,我发现了一篇关于枚举类型安全限制的有趣文章: http://www.drdobbs.com/enumerations/184401797

3 个答案:

答案 0 :(得分:2)

最大的不同是打字。枚举有一个独特的类型; 静态const必须具有现有的整数类型(尽管如此) 它可以在其他地方使用)。哪个更好取决于 你想要什么:在Direction的情况下,你可能想要 一种独特的类型,优选枚举。在其他情况下,什么 你真的想要的是一个带有整数类型的命名常量 作为数组的维度。在这些情况下,静态const是 可能更可取。

答案 1 :(得分:1)

C ++ 11 solves通过强类型枚举和改进的范围确定所有反对枚举点。

对于一组固定的值,比如你的基本方向示例,我会使用枚举。

答案 2 :(得分:1)

使用枚举,您可以将属于概念的所有常量绑定在一起(使用名为enum的唯一c ++标识符)。

Herb Sutter撰写了关于更喜欢新风格演员(static_cast)而不是C演员的文章。他的一个论点(其中之一)是它们可以在源代码中找到正则表达式。

回到你的问题,这意味着如果你采用enum,你可以通过代码库来查找一起使用的常量。对于命名空间中的常量,这是不可能的。