Range-based for loop on a dynamic array?

后端 未结 6 1067
暖寄归人
暖寄归人 2020-11-29 07:32

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

6条回答
  •  暖寄归人
    2020-11-29 07:50

    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  T* begin(std::pair const& p)
            { return p.first; }
            template  T* end(std::pair const& p)
            { return p.second; }
        }
    

    Now you can use the for-loop like this:

        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 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.

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

        template 
        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 
        wrapped_array 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;
    

    Example

提交回复
热议问题