Topic: Why basic_string != vector ?
Author: Hans-Juergen Boehm <boehm@mti.mti.sgi.com>
Date: 1997/03/16 Raw View
Saroj Mahapatra wrote:
>
> In the above piece of code, if we use non-const operator[] of the
> global var s in two different threads, we should lock it. If we
> use const operator[] of s, then this problem will not be there. In
> fact, we do have such a thread-safe implementation in our project and
> it is used in more than 100,000 lines of code without any problem.
How do you know if there is a problem?
I have myself introduced locking bugs that weren't uncovered for months
or years. Sometimes they then showed up because of different timing
on a new OS. Sometimes they were uncovered only because someone else
reading the code happenned to notice. Sometimes the system only crashes
once every two months, and it takes a while to track these things down.
It seems to me the last thing we need is a library with unintuitive and
somewhat spurious lock constraints, which are in fact hard to define
precisely. (See Jason's single threaded example.) This one's
particularly nasty, since the "window of failure" is only an instruction
or so. It seems unlikely that the problem would be correctly detected
during testing. Even if the failure were observed, I suspect most
testers would retry the test case, see that it succeeded, and then blame
the first failure on alpha-particles, or whatever.
Everyone agrees that proxy-references avoid the problem.
--
Hans-Juergen Boehm
boehm@mti.sgi.com
---
[ 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 ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: James Kanze <james-albert.kanze@vx.cit.alcatel.fr>
Date: 1997/03/17 Raw View
Jason Merrill <jason@cygnus.com> writes:
|> >>>>> James Kanze <james-albert.kanze@vx.cit.alcatel.fr> writes:
|>
|> > Hans-Juergen Boehm <boehm@mti.mti.sgi.com> writes:
|>
|> > |> a string library that doesn't. Jason Merrill has a single-threaded
|> > |> example that is also highly problematic. Even in the single-threaded
|> > |> case it is very difficult to define the semantics of such a string class
|> > |> so that it is both usable and implementable.)
|>
|> > I'd be interested in seeing the single threaded example. Jason?
|>
|> string b, c = "hi";
|>
|> c[0] = (b = c, c[1])
|>
|> In a typical copy-on-write implementation (such as mine or Rogue Wave's),
|> evaluating both the LHS and RHS will require COW even though only the LHS
|> actually does a write. If the LHS is evaluated first, the assignment will
|> modify b instead of c.
Thanks for the example. I'll admit that I don't usually write code this
way, so it didn't occur to me:-). (But I agree that an implementor must
support it.)
|> This problem can be avoided by using a reference proxy.
Which isn't legal:-(. So we are back to the starting point.
--
James Kanze home: kanze@gabi-soft.fr +33 (0)1 39 55 85 62
office: kanze@vx.cit.alcatel.fr +33 (0)1 69 63 14 54
GABI Software, Sarl., 22 rue Jacques-Lemercier, F-78000 Versailles France
-- Conseils en informatique industrielle --
---
[ 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 ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: Hans-Juergen Boehm <boehm@mti.mti.sgi.com>
Date: 1997/03/13 Raw View
Fergus Henderson wrote:
>
> Valentin Bonnard <bonnardv@pratique.fr> writes:
>
> >The question is in the subject line: why basic_string != vector ?
>
...
> (c) the implementation can optimize string in various ways that wouldn't
> be appropriate for vector, e.g. by using reference counting
> with copy-on-write.
>
This is a common technique, but it doesn't appear to be useful without
resorting to proxy-references, which are not sanctioned by CD2. The
implementation of this technique that I've seen isn't solid enough that
I could recommend use in a general purpose library. I believe the
problem is inherent. There is no way to do this acceptably.
Here is an attempt to explain what goes wrong. This is a slight
variation on observations made by others.
Consider an implementation that supports threads. (The standard doesn't
say anything about this, but most vendors would be very hesitant to ship
a string library that doesn't. Jason Merrill has a single-threaded
example that is also highly problematic. Even in the single-threaded
case it is very difficult to define the semantics of such a string class
so that it is both usable and implementable.)
Also assume that reference counting is implemented in a thread-safe
manner, i.e. such that reference count updates and fetches are atomic.
(A dubious assumption, but ...) Assume further that simultaneous
updates of a string by different threads are disallowed (as they should
be).
Consider the expression c = s[i] where s is a global reference-counted
string variable (or static member, if you prefer) and c is a character
variable. Assume s points to string data with reference count one.
Thus s[i] produces a reference to the existing character array. Before
the value at this address is retrieved and stored into c, the following
code runs in another thread:
t = s; // Add a second reference
c2 = s[j]; // Makes a new copy of s' data, since s[j] must produce
// modifiable reference.
t = ""; // Deletes the original character array associated with s,
// which was now t's data.
At this point s[i] in the original thread is a dangling reference.
This illustrates that 2 threads, both of which only read a shared
string, can interfere with each other in subtle ways that produce
intermittent errors, which would be extremely difficult to diagnose.
The fundamental problem is that the original thread has a reference (in
the C++ sense) to the original character array, but this reference
cannot be included in the reference count.
(All of this ignores performance issues.)
--
Hans-Juergen Boehm
boehm@mti.sgi.com
---
[ 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 ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: James Kanze <james-albert.kanze@vx.cit.alcatel.fr>
Date: 1997/03/14 Raw View
Hans-Juergen Boehm <boehm@mti.mti.sgi.com> writes:
|> Fergus Henderson wrote:
|> >
|> > Valentin Bonnard <bonnardv@pratique.fr> writes:
|> >
|> > >The question is in the subject line: why basic_string != vector ?
|> >
|> ...
|> > (c) the implementation can optimize string in various ways that wouldn't
|> > be appropriate for vector, e.g. by using reference counting
|> > with copy-on-write.
|> >
|>
|> This is a common technique, but it doesn't appear to be useful without
|> resorting to proxy-references, which are not sanctioned by CD2. The
|> implementation of this technique that I've seen isn't solid enough that
|> I could recommend use in a general purpose library. I believe the
|> problem is inherent. There is no way to do this acceptably.
|>
|> Here is an attempt to explain what goes wrong. This is a slight
|> variation on observations made by others.
|>
|> Consider an implementation that supports threads. (The standard doesn't
|> say anything about this, but most vendors would be very hesitant to ship
|> a string library that doesn't. Jason Merrill has a single-threaded
|> example that is also highly problematic. Even in the single-threaded
|> case it is very difficult to define the semantics of such a string class
|> so that it is both usable and implementable.)
I'd be interested in seeing the single threaded example. Jason?
|> Also assume that reference counting is implemented in a thread-safe
|> manner, i.e. such that reference count updates and fetches are atomic.
|> (A dubious assumption, but ...) Assume further that simultaneous
|> updates of a string by different threads are disallowed (as they should
|> be).
|>
|> Consider the expression c = s[i] where s is a global reference-counted
|> string variable (or static member, if you prefer) and c is a character
|> variable. Assume s points to string data with reference count one.
|> Thus s[i] produces a reference to the existing character array. Before
|> the value at this address is retrieved and stored into c, the following
|> code runs in another thread:
|>
|> t = s; // Add a second reference
|> c2 = s[j]; // Makes a new copy of s' data, since s[j] must produce
|> // modifiable reference.
|> t = ""; // Deletes the original character array associated with s,
|> // which was now t's data.
|>
|> At this point s[i] in the original thread is a dangling reference.
|>
|> This illustrates that 2 threads, both of which only read a shared
|> string, can interfere with each other in subtle ways that produce
|> intermittent errors, which would be extremely difficult to diagnose.
|>
|> The fundamental problem is that the original thread has a reference (in
|> the C++ sense) to the original character array, but this reference
|> cannot be included in the reference count.
A more fundamental problem in a threaded environment is that the second
thread could arbitrarily modify s, which will result in a dangling
reference even without copy-on-write and reference counting. (IMHO, it
is an error to worry about thread safety at this low a level, but that
is another problem.)
More generally, however, I think that a problem does exist as long as
operator[] is required to return a reference. In my own string class,
it has always returned a helper class, so as not to trigger a "copy on
write" for simple accesses, like the above.
--
James Kanze home: kanze@gabi-soft.fr +33 (0)1 39 55 85 62
office: kanze@vx.cit.alcatel.fr +33 (0)1 69 63 14 54
GABI Software, Sarl., 22 rue Jacques-Lemercier, F-78000 Versailles France
-- Conseils en informatique industrielle --
---
[ 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 ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: Jason Merrill <jason@cygnus.com>
Date: 1997/03/15 Raw View
>>>>> James Kanze <james-albert.kanze@vx.cit.alcatel.fr> writes:
> Hans-Juergen Boehm <boehm@mti.mti.sgi.com> writes:
> |> a string library that doesn't. Jason Merrill has a single-threaded
> |> example that is also highly problematic. Even in the single-threaded
> |> case it is very difficult to define the semantics of such a string class
> |> so that it is both usable and implementable.)
> I'd be interested in seeing the single threaded example. Jason?
string b, c = "hi";
c[0] = (b = c, c[1])
In a typical copy-on-write implementation (such as mine or Rogue Wave's),
evaluating both the LHS and RHS will require COW even though only the LHS
actually does a write. If the LHS is evaluated first, the assignment will
modify b instead of c.
This problem can be avoided by using a reference proxy.
Jason
---
[ 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 ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: Hans-Juergen Boehm <boehm@mti.mti.sgi.com>
Date: 1997/03/15 Raw View
James Kanze wrote:
>
> A more fundamental problem in a threaded environment is that the second
> thread could arbitrarily modify s, which will result in a dangling
> reference even without copy-on-write and reference counting. (IMHO, it
> is an error to worry about thread safety at this low a level, but that
> is another problem.)
I agree that data structures at this level should provide thread safety
only in the folllowing senses:
1) Multiple threads should be able to operate on disjoint data
structures without interference. (This is true of the SGI STL
implementation and probably of some others. It was not true of the HP
STL implementation, primarily because multiple data structures used the
same allocator, and it was not thread-safe.)
2) Multiple threads should be able to read the same (unchanging) data
structure concurrently without interference.
All bets are off if there are updates concurrent with another update or
read. (Really that means the client is responsible for locking in such
a case, as should be expected.)
Proxy-less reference-counted strings violate the second property. I find
the result extremely unnatural. That means, for example, that if I
convert program arguments to strings on program startup, and then fork
several threads I need to explicitly acquire a lock before I can examine
the arguments in a thread.
There are other problems as well. But I don't need more to convince me
that this isn't practical.
>
> More generally, however, I think that a problem does exist as long as
> operator[] is required to return a reference. In my own string class,
> it has always returned a helper class, so as not to trigger a "copy on
> write" for simple accesses, like the above.
>
I think this is the right solution. Unfortunately such helper classes
don't look enough like references to conform to the draft standard.
(Operator* for non-const iterators has exactly the same issues as
operator[] on strings.)
--
Hans-Juergen Boehm
boehm@mti.sgi.com
---
[ 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 ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: Saroj Mahapatra <saroj@nynexst.com>
Date: 1997/03/15 Raw View
Hans-Juergen Boehm wrote:
>
> Fergus Henderson wrote:
> >
> > Valentin Bonnard <bonnardv@pratique.fr> writes:
> >
> > >The question is in the subject line: why basic_string != vector ?
> >
> ...
> > (c) the implementation can optimize string in various ways that wouldn't
> > be appropriate for vector, e.g. by using reference counting
> > with copy-on-write.
> >
>
> This is a common technique, but it doesn't appear to be useful without
> resorting to proxy-references, which are not sanctioned by CD2. The
> implementation of this technique that I've seen isn't solid enough that
> I could recommend use in a general purpose library. I believe the
> problem is inherent. There is no way to do this acceptably.
>
> Here is an attempt to explain what goes wrong. This is a slight
> variation on observations made by others.
>
> Consider an implementation that supports threads. (The standard doesn't
> say anything about this, but most vendors would be very hesitant to ship
> a string library that doesn't. Jason Merrill has a single-threaded
> example that is also highly problematic. Even in the single-threaded
> case it is very difficult to define the semantics of such a string class
> so that it is both usable and implementable.)
>
> Also assume that reference counting is implemented in a thread-safe
> manner, i.e. such that reference count updates and fetches are atomic.
> (A dubious assumption, but ...) Assume further that simultaneous
> updates of a string by different threads are disallowed (as they should
> be).
>
> Consider the expression c = s[i] where s is a global reference-counted
> string variable (or static member, if you prefer) and c is a character
> variable. Assume s points to string data with reference count one.
> Thus s[i] produces a reference to the existing character array. Before
> the value at this address is retrieved and stored into c, the following
> code runs in another thread:
>
> t = s; // Add a second reference
> c2 = s[j]; // Makes a new copy of s' data, since s[j] must produce
> // modifiable reference.
> t = ""; // Deletes the original character array associated with s,
> // which was now t's data.
>
> At this point s[i] in the original thread is a dangling reference.
>
> This illustrates that 2 threads, both of which only read a shared
> string, can interfere with each other in subtle ways that produce
> intermittent errors, which would be extremely difficult to diagnose.
>
> The fundamental problem is that the original thread has a reference (in
> the C++ sense) to the original character array, but this reference
> cannot be included in the reference count.
>
> (All of this ignores performance issues.)
>
In the above piece of code, if we use non-const operator[] of the
global var s in two different threads, we should lock it. If we
use const operator[] of s, then this problem will not be there. In
fact, we do have such a thread-safe implementation in our project and
it is used in more than 100,000 lines of code without any problem.
---
[ 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 ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: Valentin Bonnard <bonnardv@pratique.fr>
Date: 1997/03/12 Raw View
The question is in the subject line: why basic_string != vector ?
basic_string provide de same basic services as vector; it just
add:
- conversion from 0 terminated string
- conversion to 0 terminated string (data/c_str)
- concatenation (+ and +=) with basic_string and string element
- operator = with 0 terminated string and string element
Basically this is:
(1) conversions with 0 terminated arrays
(2) one element work as an array
(3) concatenation
While (3) may also make sens for vector, (1) or (2) don't
often.
So my question really is: why are they independent concepts ?
(even if they aren't equivalent abstractions)
--
Valentin Bonnard
mailto:bonnardv@pratique.fr
http://www.pratique.fr/~bonnardv (Informations sur le C++ en Francais)
---
[ 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 ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: Marcelo Cantos <marcelo@mds.rmit.edu.au>
Date: 1997/03/12 Raw View
Valentin Bonnard <bonnardv@pratique.fr> writes:
> The question is in the subject line: why basic_string != vector ?
Efficiency is my guess. If you used vector to implement strings, you
would have two choices:
1. Use vector<char> as is. This would eliminate many optimisation
possibilities which are exploited in the basic_string implementation.
2. specialise vector<char>. This is no different to the current setup
and requires just as much work (perhaps more).
--
______________________________________________________________________
Marcelo Cantos, Research Assistant marcelo@mds.rmit.edu.au
Multimedia Database Systems Group, RMIT__/_ _ Tel 61-3-9282-2497
723 Swanston St, Carlton VIC 3053 Aus/ralia ><_> Fax 61-3-9282-2490
/
Acknowledgements: errors - me; wisdom - God; funding - RMIT
---
[ 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 ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: fjh@murlibobo.cs.mu.OZ.AU (Fergus Henderson)
Date: 1997/03/12 Raw View
Valentin Bonnard <bonnardv@pratique.fr> writes:
>The question is in the subject line: why basic_string != vector ?
(a) historical reasons -- string was around before STL and vector;
(b) there are some operations that string provides which don't make
sense for vector;
(c) the implementation can optimize string in various ways that wouldn't
be appropriate for vector, e.g. by using reference counting
with copy-on-write.
--
Fergus Henderson <fjh@cs.mu.oz.au> | "I have always known that the pursuit
WWW: <http://www.cs.mu.oz.au/~fjh> | of excellence is a lethal habit"
PGP: finger fjh@128.250.37.3 | -- the last words of T. S. Garp.
---
[ 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 ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: "Bradd W. Szonye" <bradds@concentric.net>
Date: 1997/03/12 Raw View
Fergus Henderson <fjh@murlibobo.cs.mu.OZ.AU> wrote in article
<5g5crc$o0v@mulga.cs.mu.OZ.AU>...
> Valentin Bonnard <bonnardv@pratique.fr> writes:
>
> >The question is in the subject line: why basic_string != vector ?
>
> (a) historical reasons -- string was around before STL and vector;
> (b) there are some operations that string provides which don't make
> sense for vector;
> (c) the implementation can optimize string in various ways that wouldn't
> be appropriate for vector, e.g. by using reference counting
> with copy-on-write.
This last part is a fairly recent change. (So recent, in fact, that some of
the text appears to contain cut-copy-paste errors and awkward verbiage.) In
pre-CD2 drafts, basic_string<> and vector<> had the same semantics for
reserve() and capacity(). In the CD2, basic_string<> gives you no
guarantees for reserve (although the actually verbiage could stand some
editing). It's turned from an allocation-pattern guarantee into a mere
hint. I expect vendors to do the Right Thing and make reserve() as tight as
possible; I believe the change occurred because the strict semantics of
vector::reserve() make implementation of lazy-copy strings non-conforming.
There simply isn't a way to do lazy-copy AND guarantee exactly when
allocation occurs, at least not without excessive legalese.
The other change I noticed: basic_string<> now behaves according to
Sequence requirements and RandomAccessible container requirements. This
means, for instance, that the constant-amortized allocation time guaranteed
by Sequences also now applies to strings. (The requirement basically
mandates geometrically rather than arithmetically expanded strings.)
Overall, I'm very pleased with the new specifications. While I don't think
that strict-copy strings are necessarily a Bad Thing, I'd hate for (a)
vendors to provide lazy strings that would have been nonconforming by the
old rules, or (b) users to avoid the string class for real or imagined
performance concerns. Ahhh, my faith in The Committee is restored! <laughs>
--
Bradd W. Szonye
bradds@concentric.net
http://www.concentric.net/~bradds
---
[ 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 ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: jbuck@Synopsys.COM (Joe Buck)
Date: 1997/03/12 Raw View
Valentin Bonnard <bonnardv@pratique.fr> writes:
>The question is in the subject line: why basic_string != vector ?
>basic_string provide de same basic services as vector; it just
>add:
>- conversion from 0 terminated string
>- conversion to 0 terminated string (data/c_str)
>- concatenation (+ and +=) with basic_string and string element
>- operator = with 0 terminated string and string element
It also provides other services for searching and substring extraction
(though most of these can be achieved with vector and STL algorithms).
It lacks some services of vector.
Certainly there is an overlap, which is why string provides iterators
so that a string can be treated as a sequence of characters, used in
STL algorithms, etc.
However, the operations commonly performed on strings differ from those
performed on other vectors, so it's worth having a different
implementation that is optimized differently. In particular, many
occurrences of the same string in a program is much more common than
many occurrences of the same vector (separate vectors with identical
contents).
So many string classes use reference counting to keep just one copy of
identical strings. There are even some implementations that permit
strings to have multiple chunks, so that concatenation doesn't require
duplication of data (the structure of a string might then resemble the
typical internal implementation of a deque).
>So my question really is: why are they independent concepts ?
They aren't. They are two different specializations of the same
underlying concept. From the latest working paper:
The template class basic_string conforms to the requirements of a
Sequence, as specified in (_lib.sequence.reqmts_). Additionally,
because the iterators supported by basic_string are random access
iterators (_lib.random.access.iterators_), basic_string conforms to
the the requirements of a Reversible Container, as specified in
(_lib.container.requirements_).
That is, any code that can work on a reversible container will work on
a string, a vector, a list, or a queue.
--
-- Joe Buck http://www.synopsys.com/pubs/research/people/jbuck.html
Help stamp out Internet spam: see http://www.vix.com/spam/
---
[ 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 ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: James Kanze <james-albert.kanze@vx.cit.alcatel.fr>
Date: 1997/03/13 Raw View
Valentin Bonnard <bonnardv@pratique.fr> writes:
|> The question is in the subject line: why basic_string != vector ?
|>
|> basic_string provide de same basic services as vector; it just
|> add:
|> - conversion from 0 terminated string
|> - conversion to 0 terminated string (data/c_str)
|> - concatenation (+ and +=) with basic_string and string element
|> - operator = with 0 terminated string and string element
|>
|> Basically this is:
|> (1) conversions with 0 terminated arrays
|> (2) one element work as an array
|> (3) concatenation
|>
|> While (3) may also make sens for vector, (1) or (2) don't
|> often.
|>
|> So my question really is: why are they independent concepts ?
|> (even if they aren't equivalent abstractions)
There are probably a number of reasons. One of the most important is
certainly the fact that it is instantiated on a "traits" class; you can
have several basic_string's implemented over char with different
multi-byte encodings (or even different single byte encodings, e.g. ISO
8859-x), for example. Each has a different type, and cannot (easily) be
mixed.
Note that the support for multibyte encoding is significant; the actual
value of an element (character) in a string cannot be determined
uniquely by looking at that element alone; it also depends on the
current mbstate.
--
James Kanze home: kanze@gabi-soft.fr +33 (0)1 39 55 85 62
office: kanze@vx.cit.alcatel.fr +33 (0)1 69 63 14 54
GABI Software, Sarl., 22 rue Jacques-Lemercier, F-78000 Versailles France
-- Conseils en informatique industrielle --
---
[ 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 ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]