是否所有C ++编译器都允许使用静态const int类成员变量作为数组绑定?

时间:2009-08-25 11:54:35

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

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

 class Class {

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

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

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

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

9 个答案:

答案 0 :(得分:13)

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

答案 1 :(得分:13)

这是有效的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 :(得分:6)

这已经是标准的C ++十多年了。它甚至得到VC的支持 - 您还想要什么? (@Neil:SunCC怎么样?:^>

答案 3 :(得分:6)

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

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

class Class {

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

希望这有帮助。

答案 4 :(得分:4)

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

  

在一些地方,C ++要求表达式计算为整数或枚举常量:作为数组边界(8.3.4,5.3.4),作为case-表达式(6.4.2),作为位字段长度(9.6) ,作为枚举器初始值设定项(7.2),作为静态成员初始值设定项(9.4.2),以及作为整数或枚举非类型模板参数(14.3)。

constant-expression:
    conditional-expression
     

一个整数常量表达式只能涉及文字(2.13),枚举数, const变量或用常量表达式初始化的整数或枚举类型的静态数据成员(8.5),非类型模板参数整数或枚举类型,以及sizeof表达式。

那就是说,似乎VC6不支持它。有关解决方法,请参阅StackedCrooked's answer。事实上,我通常更喜欢这种类型的enum方法StackedCrooked提及。

作为一个FYI,“static const”技术适用于VC9,GCC 3.4.5(MinGW),Comeau和Digital Mars。

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

答案 5 :(得分:3)

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

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

答案 6 :(得分:2)

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

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

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

并像这样使用它:

Class<5> c;

这样您就不会仅限于应用程序中的一个缓冲区大小。

答案 7 :(得分:1)

我已经不再为那些年前的便携性而烦恼了。可能仍然有编译器不支持它,但我最近没有遇到任何编译器。

答案 8 :(得分:-1)

可以通过引用ISO C ++特性来回答这样的问题,但规范很难让人们更难以阅读。 我认为最简单的答案取决于两件事:

  • Microsoft Visual Studio 2005及更高版本是一个相对一致的C ++实现。如果它允许你做某事,很可能是它的标准。
  • 下载类似Code :: Blocks的内容,让GCC编译器尝试填充。如果它在MS和GCC中有效,那么它的标准确实很可能。