10

Why std::begin() and std::end() works with array but not pointer[which is almost array] and reference of array [which is alias of original array].

After scratching my head for 15 min i am not able to get anything in google.

Below only first case works, not second and third, what could be the reason for this?

#include <iostream>
#include <vector>
#include <iterator>
#include <algorithm>

int main() 
{
   int first[] = { 5, 10, 15 };  // Fist Case

    if (std::find(std::begin(first), std::end(first), 5) != std::end(first)) {
        std::cout << "found a 5 in array a!\n";
    }

   int *second = new int[3];  // Second Case
    second[0] = 5;
    second[1] = 10;
    second[2] = 15;
    if (std::find(std::begin(second), std::end(second), 5) != std::end(second)) {
        std::cout << "found a 5 in array a!\n";
    }

    int *const&refOfFirst = first;  // Third Case

        if (std::find(std::begin(refOfFirst), std::end(refOfFirst), 5) != std::end(refOfFirst)) {
        std::cout << "found a 5 in array a!\n";
    }
}

Error:

error: no matching function for call to ‘begin(int&)’
  if (std::find(std::begin(*second), std::end(*second), 5) != std::end(*second)) {
                                  ^
3
  • 7
    Your third case is reference to a pointer, not to an array. Commented Nov 13, 2014 at 13:03
  • 3
    Since when is a pointer "almost an array"? Commented Nov 13, 2014 at 13:47
  • @JamesKanze a pointer is half an array. In the same way that an iterators is half a range :) Commented Jan 14, 2020 at 18:38

1 Answer 1

13

Given just a pointer to the start of an array, there's no way to determine the size of the array; so begin and end can't work on pointers to dynamic arrays.

Use std::vector if you want a dynamic array that knows its size. As a bonus, that will also fix your memory leak.

The third case fails because, again, you're using (a reference to) a pointer. You can use a reference to the array itself:

int (&refOfFirst)[3] = first;

or, to avoid having to specify the array size:

auto & refOfFirst = first;

and begin and end will work on this exactly as they would work on first itself.

Sign up to request clarification or add additional context in comments.

3 Comments

"Given just a pointer to the start of an array, there's no way to determine the size of the array; so begin and end can't work on pointers to dynamic arrays.", well, there is at least a begin. I have seen generic programming cases in which T* begin(T* ptr){return ptr;} would make sense to exist.
@alfC begin without end is asking for trouble.
@Caleth well, using a (single) pointer to describe a finite range is asking for trouble in the first place (OP question). In fact I don’t define an ‘end’ so you will get a compilation error eventually. My point is that you can still have generic code if what you need is a sentinel (see Rangesv3) rather than a normal end. (Some algorithms applied to an unended range are (can be) guaranteed to terminate even without and ‘end’.)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.