动态数组上基于范围的for循环?

新手上路,请多包涵

有一个基于范围的 for 循环,语法如下:

 for(auto& i : array)

它适用于常量数组,但不适用于基于指针的动态数组,例如

int *array = new int[size];
for(auto& i : array)
   cout<< i << endl;

它给出了关于替换失败的错误和警告,例如:

错误] C:\Users\Siegfred\Documents\C-Free\Temp\Untitled2.cpp:16:16: 错误:没有匹配的函数调用 ‘begin(int*&)’

如何将这种新语法与动态数组一起使用?

原文由 Maurice Rodriguez 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 764
2 个回答

要使用 _基于范围的 for 循环_,您必须提供 begin()end() 成员函数或重载非成员 begin()end() 功能。在后一种情况下,您可以将您的范围包装在 std::pair 和重载 begin()end() 中:

     namespace std {
        template <typename T> T* begin(std::pair<T*, T*> const& p)
        { return p.first; }
        template <typename T> T* end(std::pair<T*, T*> const& p)
        { return p.second; }
    }

现在您可以像这样使用 for 循环:

     for (auto&& i : std::make_pair(array, array + size))
        cout << i << endl;

Note, that the non-member begin() and end() functions have to be overloaded in the std namespace here, because pair also resides in命名空间 std 。如果您不想篡改标准命名空间,您可以简单地创建自己的小对类并在命名空间中重载 begin()end()

或者,围绕动态分配的数组创建一个瘦包装器,并提供 begin()end() 成员函数:

     template <typename T>
    struct wrapped_array {
        wrapped_array(T* first, T* last) : begin_ {first}, end_ {last} {}
        wrapped_array(T* first, std::ptrdiff_t size)
            : wrapped_array {first, first + size} {}

        T*  begin() const noexcept { return begin_; }
        T*  end() const noexcept { return end_; }

        T* begin_;
        T* end_;
    };

    template <typename T>
    wrapped_array<T> wrap_array(T* first, std::ptrdiff_t size) noexcept
    { return {first, size}; }

您的呼叫站点如下所示:

     for (auto&& i : wrap_array(array, size))
         std::cout << i << std::endl;

例子

原文由 user2218982 发布,翻译遵循 CC BY-SA 3.0 许可协议

您不能将 range-for-loop 与动态分配的数组一起使用,因为编译器无法推断该数组的开始和结束。您应该始终使用容器来代替它,例如 std::vector

 std::vector<int> v(size);
for(const auto& elem: v)
    // do something

原文由 awesoon 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题