考虑以下代码片段:
#include <iostream>
int main() {
int s[6] {0, 1, 2, 3, 4, 5};
for ( auto && i: s ) {
std::cout << " " << i << std::endl;
}
}
这在g++和clang++下都能很好地编译和运行。
这在许多帖子中被认为是理所当然的(例如,在这里和在这里),但我不清楚编译器如何能够正确地推断出for range
中没有迭代器类型的数组大小。
谁能回答或添加一个链接到参考?
根据工作草案[6.5.4/1]:
基于范围的for语句for ( for-range-declaration : for-range-initializer ) statement
等价于
{ auto &&__range = for-range-initializer ; auto __begin = begin-expr ; auto __end = end-expr ; for ( ; __begin != __end; ++__begin ) { for-range-declaration = *__begin; statement } }
,
[…]
begin-expr和end-expr的定义如下:
- 如果for-range初始化式是数组类型R的表达式,begin-expr和end-expr分别是__range和__range + __bound,其中__bound是数组的边界。如果R是未知大小的数组或不完整类型的数组,则程序是病态的;
[…]
所以它主要是像@VladFromMoscow在他的回答中已经提到的那样。
当编译器编译此语句时
for ( auto && i: s ) {
std::cout << " " << i << std::endl;
它知道变量s
是int[6]
的类型
对于数组,编译器使用像s
和s + 6
这样的表达式来定义范围。