我们可以使用for-each循环遍历传递给函数的数组吗?
我知道,我们可以通过这种方式遍历作为参数传递的数组:
//NO ERROR
void fun(int *a, int n){
for(int i=0; i<n; i++)
cout<<a[i];
}
但是,有没有什么办法可以在这样的函数中使用 for-each 循环遍历数组?
//ERROR
void fun(int *a, int n){
for(auto x:a)
cout<<x;
}
回答
指针不是数组。如果将指向数组第一个元素的指针传递给函数,则它不再是数组,而是指针。
当您通过引用传递数组时,您可以使用基于范围的循环:
#include <iostream>
template <size_t N>
void foo(int (&x)[N]) {
for (int i : x) std::cout << i << " ";
}
int main() {
int x[] = {1,2,3};
foo(x);
}
输出:
1 2 3
这是有效的,因为基于范围的循环使用std::begin(x)并std::end(x)获取迭代器到数组的开头和结尾。指针没有开始或结束。
回答
在 C++20 中,您可以使用std::span:
#include <cstddef>
#include <cstdio>
#include <span>
void foo(int* arr, std::size_t sz) {
std::span<int> span{arr, sz};
for (int elm : span) {
std::printf("%dn", elm);
}
}
或者您可以首先制作span输入参数:
void foo(std::span<int> span) {
for (int elm : span) {
std::printf("%dn", elm);
}
}
如果函数的签名是灵活的,我建议你使用第二个选项。
在 C++20 之前,这里是span来自 GSL的实现。或者使用begin()和end()函数制作自己的包装类。