46

While iterating over a vector in c++, I noticed there is a begin() function in the standard library, and also a begin() as a member function of the vector class. What, if any, is the difference between the two, and which should be used over the other?

Example:

vector<int> numbers;
//Code to put values in my vector
for (vector<int>::iterator i = numbers.begin(); i < numbers.end(); i++)
    cout << *i << '\n';

vs:

vector<int> numbers;
//Code to put values in my vector
for (vector<int>::iterator i = std::begin(numbers); i < std::end(numbers); i++)
    cout << *i << '\n';
Patryk
  • 20,424
  • 38
  • 116
  • 227
Shadow
  • 3,806
  • 5
  • 19
  • 40
  • 1
    for containers they are the same. But `std::begin` also works for built-in arrays, which is very useful in template functions. – SwiftMango Oct 10 '14 at 01:01
  • 2
    OT, but `++i` is probably more efficient than `i++` because the latter returns an iterator by value – M.M Oct 10 '14 at 02:29
  • possible duplicate of [When to use std::begin and std::end instead of container specific versions](http://stackoverflow.com/questions/8452130/when-to-use-stdbegin-and-stdend-instead-of-container-specific-versions) – edmz Oct 10 '14 at 07:58

2 Answers2

45

std::begin() was added in C++11 to make it easier to write generic code (e.g. in templates). The most obvious reason for it is that plain C-style arrays do not have methods, hence no .begin(). So you can use std::begin() with C-style arrays, as well as STL-style containers having their own begin() and end().

If you're writing code which is not a template, you can ignore std::begin(); your fellow programmers would probably find it odd if you suddenly started using it everywhere just because it's new.

John Zwinck
  • 223,042
  • 33
  • 293
  • 407
  • 4
    How about using it just because you want to be consistent? – Benjamin Lindley Oct 10 '14 at 01:09
  • @BenjaminLindley: I don't think this is exactly what @RalphWaldoEmerson had in mind when he said ""A foolish consistency is the hobgoblin of little minds," but I do think it would be distracting to see `std::begin()` used for no reason when we've done it the old way for decades. It requires more typing for no benefit. – John Zwinck Oct 10 '14 at 01:12
  • @BenjaminLindley I know you are right, and yet, I just don't want to. :( It's the same for ++it for iterators and i++ for integers. Just the way I roll. – Neil Kirk Oct 10 '14 at 01:16
  • 3
    @JohnZwinck `begin(vec)` (thanks to ADL) is less typing than `vec.begin()` :) – T.C. Oct 10 '14 at 01:24
  • 4
    Considering that if `std::begin` is available, then so are range-based for loops and `auto`; I'd prefer to not see the 2nd version at all! – M.M Oct 10 '14 at 02:28
  • 1
    @MattMcNabb: that's a great point, many uses of iterators are no longer needed at all in C++11. – John Zwinck Oct 10 '14 at 04:21
  • @neilKirk `++itr` is better than `itr++`, because it doesn't need to remember the previous iterator to return. Tons of unnecessary memory usage, and memory is one of the slower things you can do millions of times. I'll admit that compilers might be able to optimize this one for you though. I also like to think of `++itr` as "add then use and `itr++` as use then add. The first one is conceptually simpler than the second, giving it another point. Regardless, I'd recommend using one or the other consistently. What are the benefits of changing back and forth based on the type? – user904963 Nov 09 '21 at 09:52
5

The implementation of std::begin() for vectors simply calls std::vector<T>::begin(), so there is no difference between the two in this exact case.

Where std::begin() comes into its own is in generic algorithms:

template<typename Container>
void my_algorithm(Container c) {
    using std::begin;
    using std::end;
    auto const start = begin(c);  // ADL will find the appropriate overload
    auto const finish = end(c);
    // ... rest of code ...
}
Toby Speight
  • 25,191
  • 47
  • 61
  • 93