Why are std::vector::data and std::string::data different?
c++, c++11, standards
Solution
In C++98/03 there was good reason to not have a non-const `data()` due to the fact that string was often implemented as COW. A non-const `data()` would have required a copy to be made if the refcount was greater than 1. While possible, this was not seen as desirable in C++98/03.
In Oct. 2005 the committee voted in LWG 464 which added the const and non-const `data()` to `vector`, and added const and non-const `at()` to `map`. At that time, `string` had not been changed so as to outlaw COW. But later, by C++11, a COW `string` is no longer conforming. The `string` spec was also tightened up in C++11 such that it is required to be contiguous, and there's always a terminating null exposed by `operator[](size())`. In C++03, the terminating null was only guaranteed by the const overload of `operator[]`.
So in short a non-const `data()` looks a lot more reasonable for a C++11 `string`. To the best of my knowledge, it was never proposed.
Update
charT* data() noexcept;
was added `basic_string` in the C++1z working draft N4582 by David Sankel's P0272R1 at the Jacksonville meeting in Feb. 2016.
Nice job David!
Problem
Vector's new method `data()` provides a const and non-const version. However string's `data()` method only provides a const version. I think they changed the wording about `std::string` so that the chars are now required to be contiguous (like `std::vector`). Was `std::string::data` just missed? Or is the a good reason to only allow const access to a string's underlying characters? note: `std::vector::data` has another nice feature, it's not undefined behavior to call `data()` on an empty vector. Whereas `&vec.front()` is undefined behavior if it's empty.