【问题标题】:Do all C++ compilers allow using a static const int class member variable as an array bound?是否所有 C++ 编译器都允许使用静态 const int 类成员变量作为数组绑定?
【发布时间】:2009-08-25 11:54:34
【问题描述】:

在 VC++ 中,当我需要为类成员变量指定一个绑定数组时,我会这样做:

 class Class {

 private:
     static const int numberOfColors = 16;
     COLORREF colors[numberOfColors];
 };

(请不要告诉我在这里使用 std::vector)

这样我就有了一个常量,可以用作绑定数组,稍后在类代码中指定循环语句约束,同时它在其他任何地方都不可见。

问题是static const int 成员变量的这种用法是否仅由 VC++ 允许,还是其他广泛使用的编译器通常允许?

【问题讨论】:

  • “请不要告诉我在这里使用 std::vector ”——不,那不合适。你应该使用std::tr1::array:)

标签: c++ visual-c++ static constants


【解决方案1】:

这是有效的 C++ 并且大多数(全部?)相当现代的编译器都支持它。如果您使用的是 boost,您可以通过 BOOST_STATIC_CONSTANT 宏的形式获得对该功能的便携支持:

class Class {
 private:
     BOOST_STATIC_CONSTANT(int, numberOfColors = 16);
     COLORREF colors[numberOfColors];
 };

如果编译器支持,宏扩展为static const int numberOfColors = 16,否则使用enum { numberOfColors=16 };

【讨论】:

    【解决方案2】:

    根据 C++ 标准,该行为是有效的。任何最近的编译器应该支持它。

    【讨论】:

      【解决方案3】:

      我相信 Visual Studio 2005 及更高版本支持它。 XCode C++ 编译器也是如此(这实际上是 gcc)。

      如果你想安全起见,你总是可以使用我从 Effective C++ 中学到的旧枚举 hack。它是这样的:

      class Class {
      
       private:
           enum {
              numberOfColors = 16
           };
           COLORREF colors[numberOfColors];
       };
      

      希望这会有所帮助。

      【讨论】:

      • 如果您正在处理 C++ 代码,则不需要枚举“hack”,但如果您希望声明在 C 或 VC++6 中工作,这比更多我认为使用#define 的常用方法。
      【解决方案4】:

      这已经成为标准 C++ 十多年了。它甚至得到 VC 的支持——你还想要什么? (@Neil:SunCC 呢?:^>

      【讨论】:

        【解决方案5】:

        是的,它是 100% 合法的并且应该是可移植的。 C++ 标准在 5.19 - 常量表达式中说明了这一点”(强调我的):

        在几个地方,C++ 需要计算为整数或枚举常量的表达式:作为数组边界 (8.3.4, 5.3.4),作为案例表达式 (6.4.2),作为位域长度 (9.6) ,作为枚举器初始化器 (7.2),作为静态成员初始化器 (9.4.2),以及作为整数或枚举非类型模板参数 (14.3)。

        constant-expression:
            conditional-expression
        

        整型常量表达式只能包含字面量 (2.13)、枚举器、常量变量或整型的静态数据成员或使用常量表达式初始化的枚举类型 (8.5)、非类型模板参数整数或枚举类型,以及 sizeof 表达式。

        也就是说,VC6 似乎不支持它。请参阅StackedCrooked's answer 以获得良好的解决方法。事实上,我一般更喜欢 StackedCrooked 提到的 enum 方法。

        仅供参考,“static const”技术适用于 VC9、GCC 3.4.5 (MinGW)、Comeau 和 Digital Mars。

        别忘了,如果你使用“`static const'”成员,严格来说你会need a definition for it in addition to the declaration。但是,在这种情况下,几乎所有编译器都允许您跳过定义。

        【讨论】:

          【解决方案6】:

          除了其他答案,您还可以使用以下函数确定静态分配数组中的元素数量:

          template<typename T, size_t length>
          size_t arrayLength(T (&a)[length])
          {
              return length;
          }
          

          【讨论】:

            【解决方案7】:

            我很确定这也适用于 gcc 和 Solaris,但我目前无法验证。

            将来你可以像这样扩展这个想法:

            template<int size>
            class Class {
            private:
                COLORREF colors[size];
            };
            

            并像这样使用它:

            Class<5> c;
            

            这样您的应用程序中的缓冲区大小就不会受到限制。

            【讨论】:

            • 您使用的是幻数,这是问题试图避免的。
            • @Neil:但是,上面的幻数 5 可以替换为来自类的 static const int,'c' 可能会发现自己是其中的成员。
            【解决方案8】:

            几年前我就不再为便携性而烦恼了。可能还有编译器不支持它,但我最近没有遇到过。

            【讨论】:

              【解决方案9】:

              可以通过参考 ISO C++ 规范来回答此类问题,但该规范对于人们来说很难理解,也更难阅读。 我认为最简单的答案取决于两件事:

              • Microsoft Visual Studio 2005 及更高版本是一个相对一致的 C++ 实现。如果它允许你做某事,机会就是它的标准。
              • 下载 Code::Blocks 之类的内容,以获得 GCC 编译器来试用。如果它可以在 MS 和 GCC 中使用,那么很有可能是它的标准。

              【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 2016-03-03
              • 1970-01-01
              • 2021-03-19
              • 1970-01-01
              • 2021-04-06
              • 2013-01-22
              • 1970-01-01
              相关资源
              最近更新 更多