【问题标题】:Range based for-loop on array passed to non-main function传递给非主函数的数组基于范围的for循环
【发布时间】:2014-12-04 18:12:00
【问题描述】:

当我尝试在 gcc 4.8.2 中编译以下代码时,我收到以下错误:

test.cc: In function ‘void foo(int*)’:
test.cc:15:16: error: no matching function for call to ‘begin(int*&)’
   for (int i : bar) {
                ^

与来自模板库更深处的其他人一起。

#include <iostream>
using namespace std;

void foo(int*);

int main() {
  int bar[3] = {1,2,3};
  for (int i : bar) {
    cout << i << endl;
  }
  foo(bar);
}

void foo(int* bar) {
  for (int i : bar) {
    cout << i << endl;
  }
}

如果我重新定义 foo 以使用索引 for 循环,则代码编译并按预期运行。此外,如果我将基于范围的输出循环移动到main,我也会得到预期的行为。

如何将数组bar 传递给foo,使其能够对其执行基于范围的for循环?

【问题讨论】:

    标签: c++ gcc c++11 for-loop


    【解决方案1】:

    将array decaying 放入指针中,您将丢失一个重要信息:它的大小。

    使用数组引用,您的基于范围的循环可以工作:

    void foo(int (&bar)[3]);
    
    int main() {
      int bar[3] = {1,2,3};
      for (int i : bar) {
        cout << i << endl;
      }
      foo(bar);
    }
    
    void foo(int (&bar)[3]) {
      for (int i : bar) {
        cout << i << endl;
      }
    }
    

    或者,以通用方式(即在函数签名中不指定数组大小),

    template <std::size_t array_size>
    void foo(int (&bar)[array_size]) {
      for (int i : bar) {
        cout << i << endl;
      }
    }
    

    Try it out

    【讨论】:

      【解决方案2】:

      对于固定大小的数组,您可以

      • 通过引用传递原始数组。

      • 通过引用传递std::array。

      • 通过引用传递std::vector。

      自然选择(对于固定大小的数组)是std::array,即

      #include <iostream>
      #include <array>
      using namespace std;
      
      void foo(array<int, 3> const& bar) {
        for (int i : bar) {
          cout << i << endl;
        }
      }
      
      int main() {
        array<int,3> const bar = {1,2,3};
        for (int i : bar) {
          cout << i << endl;
        }
        foo(bar);
      }
      

      【讨论】:

        【解决方案3】:

        使用 C++20 的 std::span,您可以引用数组或运行时大小。

        这是您的代码,改为 std::span:

        #include <iostream>
        #include <span>
        
        void foo(std::span<int>);
        
        int main() {
          int bar[3] = {1,2,3};
          for (int i : bar) {
            std::cout << i << std::endl;
          }
          foo(bar);
        }
        
        void foo(std::span<int> bar) {
          for (int i : bar) { // now works
            std::cout << i << std::endl;
          }
        }
        

        【讨论】:

          猜你喜欢
          • 2016-08-26
          • 1970-01-01
          • 2015-10-27
          • 2013-04-01
          • 1970-01-01
          • 2016-10-31
          • 1970-01-01
          相关资源
          最近更新 更多