Topic: N2284 defect: basic_string incompletely move-aware?
Author: thorsten.ottosen@dezide.com (Thorsten Ottosen)
Date: Tue, 3 Jul 2007 13:02:06 GMT Raw View
Daniel Kr=C3=BCgler skrev:
> The synopsis of basic_string [basic.string] reveals that some relevant
> members are not move-aware, also
> they should, IMO: The following lists presents those members, which
> only provide an overload with
> const basic_string&:
>=20
> - basic_string& operator+=3D(const basic_string& str );
> - basic_string& append(const basic_string& str );
> - basic_string& insert(size_type pos1 , const basic_string& str );
> - basic_string& replace(size_type pos1 , size_type n1, const
> basic_string& str );
> - basic_string& replace(iterator i1 , iterator i2 , const
> basic_string& str );
Isn't the speed-up limited to the case where the string is empty
or the string to replace is the whole string?
-Thorsten
---
[ 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 ]
Author: =?iso-8859-1?q?Daniel_Kr=FCgler?= <daniel.kruegler@googlemail.com>
Date: Tue, 3 Jul 2007 08:06:45 CST Raw View
On 1 Jul., 17:22, Chris Jefferson <4zuma...@gmail.com> wrote:
> I believe the reason these don't have a move-aware copy is that it is
> not obvious how they could be made use of. The general opinion
> nowadays seems to be that strings should be composed of a single
> backing string.
You are right. About 2 days ago I tried to send my own correction
to this NAD, because I recognized the same thing, unfortunatly this
answer did not came into this group up to now.
My logical error was, that I compared += of basic_string with
push_back
of a container with the tiny but important difference, that += of
basic_string
accepts a basic_string and the container<T> accepts a T....
> I suppose someone could make a lazy string which was a list of blocks
> of memory which were all composed into one the first time a member was
> called which can read the contents of the string. A "compose on
> write", rather than "copy on write" :) It would have the same problems
> copy on write strings have, which is that they can be tricky in
> threads.
Right.
> I can't see why not to add them, even if no-one ever uses them, as the
> C++ standard tends to aim to allow multiple implementations.
I agree that this is possible (harmless), but could easily lead to an
overload explosion, because I could similarily argue that one should
add moveable overloads for every function currently taking a
reference to const basic_string<...>.
Thanks for your answer,
Daniel
---
[ 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 ]
Author: =?iso-8859-1?q?Daniel_Kr=FCgler?= <daniel.kruegler@googlemail.com>
Date: Tue, 3 Jul 2007 08:03:05 CST Raw View
On 28 Jun., 01:17, Daniel Kr gler <daniel.krueg...@googlemail.com>
wrote:
> The synopsis of basic_string [basic.string] reveals that some relevant
> members are not move-aware, also they should, IMO.
I reconsidered the current state of affairs and understand, that my
above given reasoning is not convincing. A move-supporting
basic_string& operator+=(const basic_string& str );
does not have more or less advantages than
bool operator==(const basic_string&, const basic_string& );
versus
bool operator==(basic_string&&, basic_string&& );
My false idea was that I compared
std::vector<T>::push_back()
(which expects a complete T instance) with
basic_string& operator+=(basic_string&& str );
which could not really *move* its argument.
Sorry for the noise,
Daniel Kr gler
---
[ 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 ]
Author: jgottman@carolina.rr.com (Joe Gottman)
Date: Wed, 4 Jul 2007 03:50:42 GMT Raw View
Daniel Kr=FCgler wrote:
> On 28 Jun., 01:17, Daniel Kr=FCgler <daniel.krueg...@googlemail.com>
> wrote:
>> The synopsis of basic_string [basic.string] reveals that some relevant
>> members are not move-aware, also they should, IMO.
>=20
> I reconsidered the current state of affairs and understand, that my
> above given reasoning is not convincing. A move-supporting
> basic_string& operator+=3D(const basic_string& str );
> does not have more or less advantages than
>=20
> bool operator=3D=3D(const basic_string&, const basic_string& );
>=20
> versus
>=20
> bool operator=3D=3D(basic_string&&, basic_string&& );
>=20
> My false idea was that I compared
>=20
> std::vector<T>::push_back()
>=20
> (which expects a complete T instance) with
>=20
> basic_string& operator+=3D(basic_string&& str );
>=20
> which could not really *move* its argument.
>=20
> Sorry for the noise,
>=20
>
I don't understand this. The reason for making=20
basic_string::operator+() move-aware is to avoid unnecessary=20
reallocation. So what's wrong with using the following algorithm in=20
operator+=3D ?
basic_string & operator+=3D(basic_string &&str)
{
size_t total_size =3D size() + str.size();
if (total_size <=3D capacity()) {
// insert str at the end of *this. No reallocation necessary
} else if (total_size <=3D str.capacity()) {
// insert *this at the beginning of str. No reallocation necessary
swap(str);
} else {
//We have to reallocate. Do so
}
return *this;
}
Joe Gottman
---
[ 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 ]
Author: Howard Hinnant <howard.hinnant@gmail.com>
Date: Wed, 4 Jul 2007 17:29:16 CST Raw View
In article <468adb5c$0$15013$4c368faf@roadrunner.com>,
jgottman@carolina.rr.com (Joe Gottman) wrote:
> Daniel Kr gler wrote:
> > On 28 Jun., 01:17, Daniel Kr gler <daniel.krueg...@googlemail.com>
> > wrote:
> >> The synopsis of basic_string [basic.string] reveals that some relevant
> >> members are not move-aware, also they should, IMO.
> >
> > I reconsidered the current state of affairs and understand, that my
> > above given reasoning is not convincing. A move-supporting
> > basic_string& operator+=(const basic_string& str );
> > does not have more or less advantages than
> >
> > bool operator==(const basic_string&, const basic_string& );
> >
> > versus
> >
> > bool operator==(basic_string&&, basic_string&& );
> >
> > My false idea was that I compared
> >
> > std::vector<T>::push_back()
> >
> > (which expects a complete T instance) with
> >
> > basic_string& operator+=(basic_string&& str );
> >
> > which could not really *move* its argument.
> >
> > Sorry for the noise,
> >
> >
> I don't understand this. The reason for making
> basic_string::operator+() move-aware is to avoid unnecessary
> reallocation. So what's wrong with using the following algorithm in
> operator+= ?
>
> basic_string & operator+=(basic_string &&str)
> {
> size_t total_size = size() + str.size();
> if (total_size <= capacity()) {
> // insert str at the end of *this. No reallocation necessary
> } else if (total_size <= str.capacity()) {
> // insert *this at the beginning of str. No reallocation necessary
> swap(str);
> } else {
> //We have to reallocate. Do so
> }
> return *this;
> }
That's a good point. I'm wondering if 17.4.4.4 [lib.member.functions]
already gives us this latitude:
2- An implementation can declare additional non-virtual member function
signatures within a class:
.
* by adding a member function signature for a member function name.
3- A call to a member function signature described in the C++ Standard
library behaves the same as if the implementation declares no additional
member function signatures.
-Howard
---
[ 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 ]
Author: =?iso-8859-1?q?Daniel_Kr=FCgler?= <daniel.kruegler@googlemail.com>
Date: Fri, 6 Jul 2007 09:24:08 CST Raw View
On Jul 4, 5:50 am, jgott...@carolina.rr.com (Joe Gottman) wrote:
> I don't understand this. The reason for making
> basic_string::operator+() move-aware is to avoid unnecessary
> reallocation. So what's wrong with using the following algorithm in
> operator+= ?
I confess that my very first reaction might have been somewhat
extreme, after realizing that the actual request was initiated due
to an error in reasoning.
I agree that move-overloads of these (and possibly some others)
mutable operations might make more sense (at least for a given
percentage of cases, not 100% as for the e.g. MoveConstruction)
than those for purely immutable operations as operator==.
Thanks for this reminder,
Daniel
---
[ 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 ]
Author: =?iso-8859-1?q?Daniel_Kr=FCgler?= <daniel.kruegler@googlemail.com>
Date: Wed, 27 Jun 2007 17:17:30 CST Raw View
The synopsis of basic_string [basic.string] reveals that some relevant
members are not move-aware, also
they should, IMO: The following lists presents those members, which
only provide an overload with
const basic_string&:
- basic_string& operator+=(const basic_string& str );
- basic_string& append(const basic_string& str );
- basic_string& insert(size_type pos1 , const basic_string& str );
- basic_string& replace(size_type pos1 , size_type n1, const
basic_string& str );
- basic_string& replace(iterator i1 , iterator i2 , const
basic_string& str );
Proposed resolution:
Add the following class members to the basic_string synopsis in
[basic.string] and to the corresponding
detailed section [string::op+=], [string::append], [string::insert],
and [string::replace]:
basic_string& operator+=(basic_string&& str );
basic_string& append(basic_string&& str );
basic_string& insert(size_type pos1 , basic_string&& str );
basic_string& replace(size_type pos1 , size_type n1, basic_string&&
str );
basic_string& replace(iterator i1 , iterator i2 , basic_string&&
str );
Greetings from Bremen,
Daniel Kr gler
---
[ 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 ]
Author: Chris Jefferson <4zumanga@gmail.com>
Date: Sun, 1 Jul 2007 09:22:56 CST Raw View
On Jun 28, 12:17 am, Daniel Kr gler <daniel.krueg...@googlemail.com>
wrote:
> The synopsis of basic_string [basic.string] reveals that some relevant
> members are not move-aware, also
> they should, IMO: The following lists presents those members, which
> only provide an overload with
> const basic_string&:
I believe the reason these don't have a move-aware copy is that it is
not obvious how they could be made use of. The general opinion
nowadays seems to be that strings should be composed of a single
backing string.
I suppose someone could make a lazy string which was a list of blocks
of memory which were all composed into one the first time a member was
called which can read the contents of the string. A "compose on
write", rather than "copy on write" :) It would have the same problems
copy on write strings have, which is that they can be tricky in
threads.
I can't see why not to add them, even if no-one ever uses them, as the
C++ standard tends to aim to allow multiple implementations.
> - basic_string& operator+=(const basic_string& str );
> - basic_string& append(const basic_string& str );
> - basic_string& insert(size_type pos1 , const basic_string& str );
> - basic_string& replace(size_type pos1 , size_type n1, const
> basic_string& str );
> - basic_string& replace(iterator i1 , iterator i2 , const
> basic_string& str );
>
> Proposed resolution:
>
> Add the following class members to the basic_string synopsis in
> [basic.string] and to the corresponding
> detailed section [string::op+=], [string::append], [string::insert],
> and [string::replace]:
>
> basic_string& operator+=(basic_string&& str );
> basic_string& append(basic_string&& str );
> basic_string& insert(size_type pos1 , basic_string&& str );
> basic_string& replace(size_type pos1 , size_type n1, basic_string&&
> str );
> basic_string& replace(iterator i1 , iterator i2 , basic_string&&
> str );
>
> Greetings from Bremen,
>
> Daniel Kr gler
>
---
[ 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 ]
Author: Mathias Gaunard <loufoque@gmail.com>
Date: Mon, 2 Jul 2007 23:14:27 CST Raw View
On Jun 28, 1:17 am, Daniel Kr gler <daniel.krueg...@googlemail.com>
wrote:
> The synopsis of basic_string [basic.string] reveals that some relevant
> members are not move-aware, also
> they should, IMO: The following lists presents those members, which
> only provide an overload with
> const basic_string&:
>
> - basic_string& operator+=(const basic_string& str );
> - basic_string& append(const basic_string& str );
> - basic_string& insert(size_type pos1 , const basic_string& str );
> - basic_string& replace(size_type pos1 , size_type n1, const
> basic_string& str );
> - basic_string& replace(iterator i1 , iterator i2 , const
> basic_string& str );
I fail to see how copying the string can be avoided in the general
case for those functions.
---
[ 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 ]