做所有 C++编译器允许使用 static const int 类成员变量作为数组边界吗?

发布于 2024-08-03 01:06:42 字数 339 浏览 4 评论 0原文

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

 class Class {

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

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

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

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

In VC++ when I need to specify an array bound for a class member variable I do it this way:

 class Class {

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

(please don't tell me about using std::vector here)

This way I have a constant that can be used as an array bound and later in the class code to specify loop-statement constraints and at the same time it is not visible anywhere else.

The question is whether this usage of static const int member variables only allowed by VC++ or is it typically allowed by other widespread compilers?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(9

╰ゝ天使的微笑 2024-08-10 01:06:42

这是有效的 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 };

This is valid C++ and most (all?) reasonably modern compilers support it. If you are using boost, you can get portable support for this feature in the form of BOOST_STATIC_CONSTANT macro:

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

The macro is expanded to static const int numberOfColors = 16 if the compiler supports this, otherwise it resorts to enum { numberOfColors=16 };.

爱,才寂寞 2024-08-10 01:06:42

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

That behavior is valid according to the C++ Standard. Any recent compiler should support it.

你爱我像她 2024-08-10 01:06:42

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

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

class Class {

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

希望这有帮助。

I believe that Visual Studio 2005 and beyond supports it. The XCode C++ compiler as well (this is gcc actually).

If you want to be safe you could always use the old enum hack that I learned from Effective C++. It goes like this:

class Class {

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

Hope this helps.

青瓷清茶倾城歌 2024-08-10 01:06:42

十多年来,它一直是 C++ 的标准。它甚至得到了 VC 的支持——你还想要什么呢? (@Neil:SunCC 怎么样?:^>

This has been standard C++ for more than a decade now. It's even supported by VC -- what more could you want? (@Neil: What about SunCC? :^>)

嘿看小鸭子会跑 2024-08-10 01:06:42

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

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

常量表达式:
    条件表达式

整型常量表达式只能涉及文字 (2.13)、枚举器、常量变量或用常量表达式初始化的整型或枚举类型的静态数据成员 (8.5)、整型或枚举类型以及 sizeof 表达式。

也就是说,VC6 似乎不支持它。请参阅StackedCrooked 的回答提供了一个很好的解决方法。事实上,我通常更喜欢 StackedCrooked 提到的这种类型的 enum 方法。

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

并且不要忘记,如果您使用“static const”成员,您将 除了声明之外还需要一个定义。然而,在这种情况下,几乎所有编译器都会让您跳过定义。

Yes, it's 100% legal and should be portable. The C++ standard says this in 5.19 - Constant expressions" (emphasis mine):

In several places, C++ requires expressions that evaluate to an integral or enumeration constant: as array bounds (8.3.4, 5.3.4), as case-expressions (6.4.2), as bit-field lengths (9.6), as enumerator initializers (7.2), as static member initializers (9.4.2), and as integral or enumeration non-type template arguments (14.3).

constant-expression:
    conditional-expression

An integral constant-expression can involve only literals (2.13), enumerators, const variables or static data members of integral or enumeration types initialized with constant expressions (8.5), non-type template parameters of integral or enumeration types, and sizeof expressions.

That said, it appears that VC6 doesn't support it. See StackedCrooked's answer for a good workaround. In fact, I generally prefer the enum method StackedCrooked mentions for this type of thing.

As an FYI, the "static const" technique works in VC9, GCC 3.4.5 (MinGW), Comeau and Digital Mars.

And don't forget that if you use a "`static const'" member, you'll need a definition for it in addition to the declaration strictly speaking. However, virtually all compilers will let you get away with skipping the definition in this case.

痕至 2024-08-10 01:06:42

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

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

Besides other answers you can use following function do determine number of elements in statically alocated arrays:

template<typename T, size_t length>
size_t arrayLength(T (&a)[length])
{
    return length;
}
不气馁 2024-08-10 01:06:42

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

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

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

并像这样使用它:

Class<5> c;

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

I'm pretty sure that this will also work with gcc and Solaris, but I can't verify this at the moment.

In the future you could extend the idea like this:

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

and use it like this:

Class<5> c;

so that you are not limited to exactly one buffer size in your application.

海拔太高太耀眼 2024-08-10 01:06:42

几年前我就不再担心它的可移植性了。也许仍然有不支持它的编译器,但我最近还没有遇到过它们。

I've stopped bothering about the portability of that years ago. There are perhaps still compilers which don't support it, but I haven't met any of them recently.

一页 2024-08-10 01:06:42

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

  • Microsoft Visual Studio 2005 及更高版本是相对一致的 C++ 实现。如果它允许你做某事,那么机会就是它的标准。
  • 下载类似 Code::Blocks 的东西来获取 GCC 编译器来尝试一些东西。如果它在 MS 和 GCC 中工作,那么很可能确实是它的标准。

It is possible to answer questions like this by referencing the ISO C++ speicifcation but the spec is hard for people to get and harder to read.
I think the simplest answer hinges on two things:

  • Microsoft Visual Studio 2005 and up is a relatively conformant C++ implementation. If it allows you to do something, chances are its standard.
  • Download something like Code::Blocks to get a GCC compiler to try stuff out. If it works in MS and GCC, chances really are, its standard.
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文