微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

我们可以使用 for-each 循环遍历传递给函数的数组吗?

如何解决我们可以使用 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;
    }

解决方法

在 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("%d\n",elm);
  }
}

或者您可以首先将 span 作为输入参数:

void foo(std::span<int> span) {
  for (int elm : span) {
    std::printf("%d\n",elm);
  }
}

如果函数的签名是灵活的,我建议你使用第二个选项。

在 C++20 之前,here 是来自 GSL 的 span 的实现。或者使用 begin()end() 函数创建自己的包装类。

,

指针不是数组。如果你将一个指向数组第一个元素的指针传递给一个函数,那么它就不再是一个数组,而是一个指针。

当您pass the array by reference时可以使用基于范围的循环:

#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 解决方案:

auto range = std::views::counted(arr,sz);
for (auto elm : range) {

std::span 相比,这样做的好处是它更通用并且适用于任何迭代器,不需要像指针这样的连续迭代器。

使用 std::span 代替它的好处是您可以将 std::span 用作函数参数,而无需将其设为模板。


替代模板解决方案(适用于 C++20 之前):

template <class Range>
void foo(const Range& range) {
    for (auto elm : range) {

int (&arr)[N] 相比,这样做的好处是它更通用。此模板适用于所有范围。


除了 range-for,您还可以考虑完全避免循环(在 C++20 之前有效):

auto print = [](auto elm) {
    std::cout << elm;
}
std::for_each_n(arr,sz,print);

如果你没有 C++20,由于某种原因不能有 boost/ranges/GSL 库,并且没有模板,我推荐这个。

,

是的,你可以。只需通过引用模板函数传递数组:

#include <iostream>
using namespace std;
 
template <size_t N> void foo(int (&arr)[N])
{
    for (auto i:arr)
        cout << i << " ";
}
 
int main()
{
    int array[] = { 5,17,3452,546546,756756,75675,756753,345,53};
    foo(array);
    return 0;
}
,

和真正的答案:

    int made[] = {10,15};
    std::for_each(std::begin(made),std::end(made),[=](auto x){ std::cout << x << std::endl; });

您可以将 std::for_each 与 say std::execution::par 并行化。

带有函数代码的将

#include <iostream>
#include <vector>
#include <execution>

void f(int (&made)[3])
{
     std::for_each(std::begin(made),[=](auto x){ std::cout << "and then " << x << std::endl; });
}

int main(int argc,char *argv[])
{

    int made[] = {10,15};
    f(made);
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。