Re: Non-const overload of std::string::data()
Greg Herlihy ha scritto:
On 5/31/07 12:30 PM, in article e%e7i.23624$%k.105776@twister2.libero.i=
t,
"Alberto Ganesh Barbati" <AlbertoBarbati@libero.it> wrote:
(this is a follow-up of thread "std::string::data()" in
comp.lang.c++.moderated)
The latest draft (N2284) includes wording from issue #530, which adds =
a
requirement to std::basic_string: the string elements must be stored
contiguously in memory. It has been noticed in the cited thread that
such a requirement effectively makes it possible to use the expression
&s[0] to portably obtain a non-const pointer to the string internal bu=
ffer.
Not quite: according to N2284 &s[0] points to a character buffer that i=
s
neither modifiable (see =A721.3.4) nor internal to the std::string o=
bject (see
Table 39). Furthermore, there is no requirement that a std::string even=
has
to maintain an internal character buffer as such in the first place.
I'm sorry but =A721.3.4 of N2284 is about capacity(), resize() etc. an=
d I
don't see how is it relevant, while table 39 is about allocators not
strings. Are you sure you referring to N2284? Would you care check your
references, please?
I base my claim on these statements:
=A721.3.5/1: if s is not const and non-empty, s[0] returns a *modifiab=
le*
reference to *begin() and p = &s[0] is therefore a pointer that can be
dereference to modify the first element of the sequence.
=A721.3.1/3: guarantees that p + n is the same as &*(begin() + n) so p=
[n]
can be used to modify the nth element of the sequence
basic_string has a const data() member, but not a non-const overload.
However, obtaining a non-const pointer to the internal buffer is perha=
ps
the #1 FAQ about basic_string. Whatever rationale there was for not
providing the non-const overload has now been superseded by #530, IMHO.
I say we should just provide it.
What for? A non-const data() overload would create the false impression=
that
the non-const data() overload could be used to modify the string itself=
- a
sheer impossibility in light of a std::string's design guarantees.
Specifically: in order to support std::string implementations that use
reference-counting - every modification to a std::string object must be
mediated by its class interface. So, at the very least, a non-const
std::string data() method would break every existing reference-counted
std::string implementation, by bypassing std::string's interface.
Adding non-const data() wouldn't break anything more than =A721.3.5/1
already does. The standard already says that references, pointers and
iterators are invalidated by a call to data(). Simply calling data() can
just mark the string as unsharable. This must *already* occur for
operator[], because of this:
void foo()
{
std::string s1 = "hello, world";
char& c1 = s1[0];
std::string s2(s1); // doesn't invalidate c1
c1 = 'j'; // shall modify s1 but not s2
}
The example above shows that s1 and s2 can't share the same buffer. This
can be obtained even with a ref-counted implementation, by having
operator[] mark s1 as unsharable.
So why not data()?
Ganesh
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]