5

Is std::vector::begin() from prior-C++11 equivalent to std::vector::data() in C++11? The reason I'm asking this, earlier than C++11, I used to treat std::vector::begin() as a pointer but after C++11, it's not, and i cannot cast to a pointer equivalent. So, can I use data() instead after C++11?

Dr. Debasish Jana
  • 6,980
  • 4
  • 30
  • 69

3 Answers3

8

No, begin returns an iterator, whereas data returns a pointer. For a given implementation, these may be the same thing, but you shouldn't count on this.

TartanLlama
  • 63,752
  • 13
  • 157
  • 193
  • In addition to this, the memory of `std::vector` was not guaranteed to be contiguous before C++11 -- though in practice an implementation that does otherwise would perhaps be a bit silly. – alcedine May 04 '16 at 13:18
  • 7
    @alcedine Actually that was rectified in C++03. It was only C++98 and before that did not guarantee it. – NathanOliver May 04 '16 at 13:22
  • 2
    @alcedine, not true. Was contiguos from at least 2003, and I have a pretty strong feeling it was contiguos in 98. – SergeyA May 04 '16 at 13:30
  • 1
    Very few implementations actually have iterators as pointers nowadays. – SergeyA May 04 '16 at 13:31
  • 3
    @alcedine: You're thinking of `std::string`. `std::vector` has always been contiguous, because it's always been designed as a wrapper around a buffer usable for C interop. – Ben Voigt May 04 '16 at 13:33
  • 2
    As a matter of fact, I was not able to find any normative requirements in 98 standard for vector to be contiguos... – SergeyA May 04 '16 at 13:37
  • 1
    @SergeyA: I can't find an explicit statement either. On the other hand, there are some requirements around pointer invalidation which might be hard to meet with non-contiguous storage. As a whole, the entire thing is badly underspecified though. – Ben Voigt May 04 '16 at 13:41
  • I stand corrected in that it was C++98, but I believe I do have the correct container: http://stackoverflow.com/questions/849168 – alcedine May 04 '16 at 13:43
  • Yeah C++ 98 doesn't come out and say it but making a non-contiguous vector that satisfies all of the vector requirements is just silly as it would be overly complex and maybe not possible. For all intents and purposes it is fine. If you have an implementation where it not I would suggest just getting a new implementation. – NathanOliver May 04 '16 at 13:44
4

Using iterator as pointer is completely wrong, because of it is implementation-defined. If you still need pointer to data at iterator you should use address of dereferenced iterator, like this:

std::vector<int> v; v.push_back(42);
std::vector<int>::iterator it = v.begin();
int * p = &*it;

And of course, in c++11 you can use .data() as pointer to vector elements.

user2807083
  • 2,962
  • 4
  • 29
  • 37
2

Is std::vector::begin() from prior-C++11 equivalent to std::vector::data() in C++11?

Depends what you mean by equivalent. Dereferencing either will yield a reference to the first item in the vector, but the iterator returned by begin() is not guaranteed to be convertible to the pointer type returned by data().

The reason I'm asking this, earlier than C++11, I used to treat std::vector::begin() as a pointer but after C++11, it's not, and i cannot cast to a pointer equivalent.

Your code worked through good (or bad) luck, depending on how you look at it.

So, can I use data() instead after C++11?

There are two iterator pairs that straddle the vector's data:

begin() to end()

and

data() to data() + size()

you can use either in any standard algorithm and the result will be the same.

As a matter of good style you ought to use begin() to end() where you can (which will be almost always).

Richard Hodges
  • 68,278
  • 7
  • 90
  • 142