4

This works:

void foo(int (&a)[3]) {
    auto ibegin = begin(a);
    auto ebegin = end(a);
}

While this doesn't:

void foo(int (*a)[3]) {
    auto ibegin = begin(a);
    auto ebegin = end(a);
}

I consider int (&a)[3] and int (*a)[3] have the same meaning!

DeiDei
  • 10,205
  • 6
  • 55
  • 80
Rick
  • 7,007
  • 2
  • 49
  • 79

5 Answers5

8

Your code is analogous to:

void foo(vector<int>& a) {
    auto ibegin = begin(a);
    auto ebegin = end(a);
}

void foo(vector<int>* a) {
    auto ibegin = begin(a);
    auto ebegin = end(a);
}

The first one works and the second one doesn't for the same reason as it works on int (&a)[3] and doesn't on int (*a)[3]. When you're using pointers to collections instead of references, you need to dereference them when you pass them to the standard library's begin/end.

void foo(vector<int>* a) {
    auto ibegin = begin(*a);
    auto ebegin = end(*a);
}

void foo(int (*a)[3]) {
    auto ibegin = begin(*a);
    auto ebegin = end(*a);
}
zneak
  • 134,922
  • 42
  • 253
  • 328
  • (@thedeg123, see other examples of ["analogous to"](https://www.merriam-webster.com/dictionary/analogous). I'm fairly confident that it should be "to" and not "too".) – zneak May 15 '18 at 03:11
  • Thanks! All the answers explain well but your example is inspiring to me. I don't know that I can still use std::begin/std::end after dereferencing the pointer to array. – Rick May 15 '18 at 03:17
  • 1
    Yes, it works because dereferencing gets you a reference: for `int (*a)[3]`, `*a` has the type `int (&)[3]`, and it refers to the same object. – zneak May 15 '18 at 03:18
  • 1
    Apologies @zneak my mistake. – thedeg123 May 15 '18 at 03:26
7

I consider int (&a)[3] and int (*a)[3] have the same meaning!

Absolutely not. int (&a)[3] declares a reference to array, and int (*a)[3] declares a pointer to array. These are different in most of the same ways a reference to int and a pointer to int are different. (Though when C-style arrays are involved, the automatic array-to-pointer conversion sometimes complicates things.)

aschepler
  • 70,891
  • 9
  • 107
  • 161
4

I consider int (&a)[3] and int (*a)[3] have the same meaning!

No! The first one is a reference to an array, the second is a pointer to an array.

In C++14 std::begin and std::end are defined as:

template<class T, std::size_t N> 
constexpr T* begin(T (&array)[N]) noexcept;

template<class T, std::size_t N> 
constexpr T* end(T (&array)[N]) noexcept;

Clearly, the functions take a reference to an array, not a pointer.

DeiDei
  • 10,205
  • 6
  • 55
  • 80
  • Thanks for the quick reply! Btw, since I don't have to pass a size of a array while using reference(inside the function I can still use begin and end), so reference parameter for an array is practically better and used than pointer parameter for an array in all circumstances? – Rick May 15 '18 at 03:02
  • 1
    @Rick Yes, the pointer+size function parameters are discouraged in C++. Better yet, there's `std::array`. – DeiDei May 15 '18 at 03:04
4

You may understand the difference in function overloading where the three are respectively reference to array, pointer to array and array of pointers. So they don't have the same meaning.

#include <iostream>

void foo(int (&a)[3]) {
    std::cout << "(&a)[3]" << std::endl;
}

void foo(int (*a)[3]) { 
    std::cout << "(*a)[3]" << std::endl;
}

void foo(int *a[3]) {
    std::cout << "*a[3]" << std::endl;
}

int main() {
    int m[3];
    int *n[3] = {m + 0, m + 1, m + 2};
    foo(m);       // (&a)[3]
    foo(&m);      // (*a)[3]
    foo(n);       // *a[3]
}
Blownhither Ma
  • 1,461
  • 8
  • 18
1

The & symbol is getting the location of the pointer in (&a) you are getting the address of a at location 0 in the array.

While *a is getting the value stored at a[0] this is called dereferencing a pointer. For example:

int * a = {0,1,2};

&a[0] //gets value of the memory pointer of a[0], maybe 0xff123
*a[0] //dereferences the pointer at [0] in this gets case '0'.

For a more complete look at pointers, I'd check out: What does "dereferencing" a pointer mean?

thedeg123
  • 408
  • 2
  • 5
  • 11