在C++ 11之前的"常量表达式"

Kyl*_*and 13 c++ compile-time-constant constant-expression c++03 c++98

constexpr关键字是在C++ 11中引入的,因为(我认为)是"常量表达式"的相应概念.但是,这个概念隐含在C++ 98/c ++ 03中,因为数组声明需要一个常量表达式:

// valid:
int a[sizeof(int)];
int b[3+7];
int c[13/4];
const int n = 3;
int d[n];
// invalid:
int m = 4;
int e[m];
Run Code Online (Sandbox Code Playgroud)

还有其他"常量表达式",即可以在编译时评估(和/或必须)的表达式; 一个例子是模板参数.

对于预C++ 11,在C++ 98/03标准或其他地方是否存在以下情况?

  • 需要常量表达式的语法结构的完整列表(例如数组声明和模板实例化)
  • 管理这种常量表达式的规则(可能这只是从上面列表中的项到它们在标准中的定义的映射)

Sha*_*our 12

constexpr常量表达式是相关的,因为constexpr告诉我们可以使用变量或函数,其中可以使用常量表达式.这就是cppreference告诉我们的:

constexpr说明符声明可以在编译时评估函数或变量的值.然后可以在仅允许编译时常量表达式的情况下使用这些变量和函数.

恒定expresions存在之前C++ 11和管辖常量表达式预先C++ 11的规则在同一地方被覆盖C++ 03标准草案(这是可用的最接近的最早公开草案C++ 03)1作为C++ 11标准草案的部分5.19 常量表达式,cppreference在常量表达式页面中对此主题有一个很好的总结,但它面向C++ 11和C++ 14并且很难说出什么适用于前C + +11.

标准的预C++ 11列出了需要常量表达式的地方,在第一段中5.19看起来很完整:

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

1段的其余部分说:

一个整数常量表达式只能涉及算术类型的文字(2.13,3.9.1),枚举数,非易失性常量变量或用常量表达式(8.5)初始化的整数或枚举类型的静态数据成员,非类型模板参数整数或枚举类型,以及sizeof表达式.浮动文字(2.13.3)只有在转换为整数或枚举类型时才会出现.只能使用转换为整数或枚举类型的转换.特别是,除了sizeof表达式之外,不应使用函数,类对象,指针或引用,并且不应使用赋值,递增,递减,函数调用或逗号运算符.

然后是5更多列出进一步要求的段落.

在C++ 11中,有一个列表,其中可以在第3段中使用常量表达式,但它没有说明它们的位置.您可能必须搜索术语常量表达式以查找所需的所有位置,并且通常会有类似于以下的短语:

应该是一个不变的表达

是因为违反了一个重要的长期要求使得病态的程序.

或者,您可以使用Annex A 语法摘要并搜索常量表达式,并且应该覆盖语法中需要常量表达式的所有位置,例如:

enumerator = constant-expression
Run Code Online (Sandbox Code Playgroud)

脚注:

  1. 这个答案我在哪里可以找到当前的C或C++标准文档?有完整的标准草案清单.不幸的是,最接近公众的是早期2005.早期版本需要身份验证.据我所知,部分5.19没有太大变化.