C++ 11基于范围的for循环如何知道数组大小?

MrF*_*Fox 9 c++ for-loop c++11

当我做这样的事情时:

int my_array[5] = {1, 2, 3, 4, 5};
for (int &x : my_array) {
    x *= 2;
}
Run Code Online (Sandbox Code Playgroud)

C++ 11显然知道我的数组只有5个元素.这些信息是否存储在my_array对象的某个位置?

如果是这样,有什么理由说明为什么它不能作为开发人员提供给我(或者是它?!?!?)?如果C++开发人员总是知道他们正在处理的数组的界限,似乎很多世界的问题都将得到解决.

Ker*_* SB 12

这只是语言需要工作的东西,编译器必须实现.显然,完整类型my_arrayint[5](即大小是类型的一部分),因此这些信息很容易获得.

与流行的看法相反,没有使用游戏中的免费std::begin()/ std::end()功能,虽然那些天真似乎能够做到这一点(但是有一个涉及ADL的攻击会破坏这种方法).

  • @suslik:当然,因为数组不是类类型,因此不能有成员函数.但是你可以简单地编写一个产生所需值的`array_size`自由函数模板,或者使用随手可得的[`std :: extent`](http://en.cppreference.com/w/cpp/types/extent ). (6认同)
  • @suslik:因为`std :: extent`也是新的C++ 11.那些机制(作为类型的一部分的数组类型)不是新的,因此总是可以编写`std :: extent`.他们直到最近才这样做. (3认同)

Pub*_*bby 6

它是可用的 - 您可以在标准C++中定义beginend使用数组.数组的大小以类型编码.

一般方法是使用对数组的引用.

这是一个示例大小函数:

template<typename T, size_t N>
size_t array_size(T (& const)[N])
{
    return N;
}
Run Code Online (Sandbox Code Playgroud)

  • 这也称为`std :: extent`.并且`std :: begin`和`std :: end`已经*已经为标准库中的数组定义了. (6认同)

Pet*_*ker 5

不,它不是对象的一部分.但它是这种类型的一部分.这就是5数组声明中的内容.但是,这不起作用:

void f(int arr[5]) {
    for(int& x: arr) {
        // whatever
    }
}
Run Code Online (Sandbox Code Playgroud)

因为这里的数组名称衰减为指向其第一个元素的指针,也就是说,参数声明等效于int *arr没有大小信息.

  • 在这种情况下,我不会使用"衰变"一词.我认为该术语通常特定于在许多表达式中对数组变量进行的隐式转换.`int a [5]; a + 1; //衰变`相反,我喜欢用术语"调整"来指代这里发生的事情,就像标准使用的那样.`void foo(int a [5]); //输入'adjust':相当于void foo(int*a)`.当我说出这个词时,我喜欢用讽刺的语调. (3认同)