NuPagadi
NuPagadi

Reputation: 1440

How to use range for for arrays being passed to function

I want to write a function, to which an array is passed, and have a possibility to use range for inside. I managed to do it for a fixed-size array only.

void print(unsigned (&arr)[11]){
    for (unsigned val : arr)
        cout << val << ' ';
    cout << endl;
}

void main() {
    unsigned arr[11] = {};    
    print(arr);
}

How to do it for variable-size arrays? Thx.

Upvotes: 1

Views: 105

Answers (2)

Yakk - Adam Nevraumont
Yakk - Adam Nevraumont

Reputation: 275395

My preferred solution is to do a bit of type erasure here.

template<typename T>
struct contig_range_view {
  // leave these public.  Why not?
  T const* b = nullptr;
  T const* e = nullptr;
  // this means you support for( T x : me ) loops:
  T const* begin() const { return b; }
  T const* end() const { return e; }
  // While we are here, lets support [] indexing and .size(), because:
  T const& operator[](unsigned i) const { return b[i]; }
  std::size_t size() const { return e-b; }
  // default copy/construct/assign:
  contig_range_view() = default;
  contig_range_view(contig_range_view const&) = default;
  contig_range_view& operator=(contig_range_view const&) = default;
  // conversion from [] style arrays, std::arrays, and std::vector (implicit):
  template<unsigned N>
  contig_range_view( const T(&arr)[N] ):b(arr), e(arr+N) {}
  template<unsigned N>
  contig_range_view( std::array<T, N> const&arr ):b(&arr[0]), e(b+N) {}
  template<typename A>
  contig_range_view( std::vector<T, A> const& v ):b(v.data()), e(v.data()+v.size()) {}
};

// example use.  Far less terrifying than the above, isn't it?
void print( contig_range_view<unsigned> arr ) {
  for (unsigned x : arr) {
    std::cout << x << ",";
  }
  std::cout << "\n";
}

this has the advantage of allowing the implementation of print to live in a different compilation unit than its interface or where it is called.

And it supports std::array and std::vector for free (as they have identical binary layouts to [] style arrays, why not?)

Upvotes: 4

Iban Cereijo
Iban Cereijo

Reputation: 1675

For other sizes known at compile time:

template <unsigned N>
void print(unsigned (&arr)[N]){
    for (unsigned val : arr)
      cout << val << ' ';
    cout << endl;
}

int main() {
    unsigned arr[11] = {};
    unsigned arr2[12] = {};

    print(arr);
    print(arr2);

    return 0;
}

Upvotes: 6

Related Questions