本文介绍了动态数组上基于范围的for循环?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

There is a range-based for loop with the syntax:

for(auto& i : array)

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

It works with constant arrays but not with pointer based dynamic ones, like

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

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

It gives errors and warnings about failure of substitution, for instance:

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

如何将这种新语法用于动态数组?

How do I use this new syntax with dynamic arrays?

推荐答案

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

To make use of the range-based for-loop you have to provide either begin() and end() member functions or overload the non-member begin() and end() functions.In the latter case, you can wrap your range in a std::pair and overload begin() and end() for those:

    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 循环:

Now you can use the for-loop like this:

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

注意,这里的非成员 begin()end() 函数必须在 std 命名空间中重载,因为pair 也位于命名空间 std 中.如果您不想篡改标准命名空间,您可以简单地创建自己的小对类并在命名空间中重载 begin()end().

Note, that the non-member begin() and end() functions have to be overloaded in the std namespace here, because pair also resides in namespace std. If you don't feel like tampering with the standard namespace, you can simply create your own tiny pair class and overload begin() and end() in your namespace.

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

Or, create a thin wrapper around your dynamically allocated array and provide begin() and end() member functions:

    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}; }

您的呼叫站点如下所示:

And your call site looks like this:

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

示例

这篇关于动态数组上基于范围的for循环?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-11 00:25