5

似乎 C++11 中可用的“for each”语法风格允许数组迭代,而不需要知道数组的实际大小(元素数量)。我假设,因为它是新标准的一部分,所以这是完全安全的,即使对于 C 数组也是如此。通常,您还必须在操作之前单独知道 C 数组的大小,但我希望任何使用过这种新 C++ 技术的人验证它的工作方式完全符合您的预期:

extern float bunch[100];

for (float &f : bunch) {
  f += someNumber;
}

关于这种技术的非明显副作用或缺点,我有什么需要了解的吗?它在我看到的代码中没有显示太多,可能是因为大多数代码都是在标准中之前编写的。想确保它的罕见用法不是因为其他一些不为人知的原因。

4

3 回答 3

4

这种用法没有什么奇怪或不安全的。数组的大小在编译时是已知的,因此可以在循环中使用。这是一个模板函数的示例,它允许您找出数组的长度:

template< class T, std::size_t N >
std::size_t length( const T (&)[N] )
{
  return N;
}

Foo f[5];
std::cout << length(f) << "\n";

这应该清楚地表明您不能在动态大小的 C 样式数组上使用这种技术或基于范围的循环。

当然,如果您有基于范围的循环,那么您也应该有std::array(如果没有,您可能可以从std::tr1或 boost 中获取 ti),因此您可以完全避免使用 C 样式的数组:

extern std::array<float, 100> bunch;

for (auto &f : bunch) {
  f += someNumber;
}
于 2013-01-21T13:41:11.420 回答
4

对数组使用基于范围的 for 循环是非常安全的。我想你担心你可能会不小心在指针上使用它:

float* array = new float[100];
for (float& f : array) {
    // ...
}

不过不用担心。在这种情况下,编译器会产生错误。因此,在不安全的情况下,无论如何您都会收到编译错误。

于 2013-01-21T13:46:10.957 回答
2

数组可以作为引用传递,并推导出它们的类型和长度。

#include <iostream>

template<typename T, size_t N>
void fun(T const (&arr)[N])
{
    for (std::size_t i = 0; i < N; ++i)
       std::cout << arr[i] << " ";
}

int main()
{
   int x[] = { 1, 2, 3 }; // no need to set length here
   fun(x); // 1 2 3, no need to specify type and length here
}
于 2013-01-21T13:37:52.603 回答