Topic: Redundant move constructors?


Author: "Bo Persson" <bop@gmb.dk>
Date: Mon, 21 Sep 2009 18:26:45 CST
Raw View
I have a hard time finding a use case for the second of these
constructors:

basic_string(basic_string&& str);
basic_string(basic_string&&, const Allocator&);

The first one will aquire all its contents from the str parameter,
including str's allocator.

But, if I find a need to pass a separate allocator instance to the
constructor (second case), isn't it highly likely that this allocator
will compare unequal to str's allocator? Why else would I need a
different one?

In they compare unequal, I believe we need to allocate a new string
buffer and copy all the characters over. So what is the advantage of
having an rvalue reference here?


Bo Persson



--
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@netlab.cs.rpi.edu]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: "Leigh Johnston" <leigh@i42.co.uk>
Date: Tue, 22 Sep 2009 09:53:18 CST
Raw View
All instances of an allocator have to be equivalent so there is nothing to
compare.

/Leigh

"Bo Persson" <bop@gmb.dk> wrote in message
news:7hq72uF2tup0bU1@mid.individual.net...
>I have a hard time finding a use case for the second of these
> constructors:
>
> basic_string(basic_string&& str);
> basic_string(basic_string&&, const Allocator&);
>
> The first one will aquire all its contents from the str parameter,
> including str's allocator.
>
> But, if I find a need to pass a separate allocator instance to the
> constructor (second case), isn't it highly likely that this allocator
> will compare unequal to str's allocator? Why else would I need a
> different one?
>
> In they compare unequal, I believe we need to allocate a new string
> buffer and copy all the characters over. So what is the advantage of
> having an rvalue reference here?
>
>
> Bo Persson
>
>
>
> --
> [ comp.std.c++ is moderated.  To submit articles, try just posting with ]
> [ your news-reader.  If that fails, use mailto:std-c++@netlab.cs.rpi.edu]
> [              --- Please see the FAQ before posting. ---               ]
> [ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]
>


--
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@netlab.cs.rpi.edu]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: "Bo Persson" <bop@gmb.dk>
Date: Tue, 22 Sep 2009 17:34:20 CST
Raw View
Leigh Johnston wrote:
> All instances of an allocator have to be equivalent so there is
> nothing to compare.

Then there would be even less reason to pass a separate instance to
the constructor.  :-)

>From what I understand, the current standard allows implementations to
make this assumption, but encourages implementors to support non-equal
instances. C++0x seems to (at least want to) require it.

So, what do I use the second constructor for - if the allocator
instance is different, I have to copy the string data, so why an
rvalue. If the allocator is equal, why pass a new instance?


Bo Persson

>
> /Leigh
>
> "Bo Persson" <bop@gmb.dk> wrote in message
> news:7hq72uF2tup0bU1@mid.individual.net...
>> I have a hard time finding a use case for the second of these
>> constructors:
>>
>> basic_string(basic_string&& str);
>> basic_string(basic_string&&, const Allocator&);
>>
>> The first one will aquire all its contents from the str parameter,
>> including str's allocator.
>>
>> But, if I find a need to pass a separate allocator instance to the
>> constructor (second case), isn't it highly likely that this
>> allocator will compare unequal to str's allocator? Why else would
>> I need a different one?
>>
>> In they compare unequal, I believe we need to allocate a new string
>> buffer and copy all the characters over. So what is the advantage
>> of having an rvalue reference here?
>>
>>
>> Bo Persson
>>
>>



--
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@netlab.cs.rpi.edu]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: Pablo Halpern <phalpern@halpernwightsoftware.com>
Date: Wed, 23 Sep 2009 01:05:41 CST
Raw View
On Sep 22, 7:34 pm, "Bo Persson" <b...@gmb.dk> wrote:
> Leigh Johnston wrote:
> > All instances of an allocator have to be equivalent so there is
> > nothing to compare.
>
> Then there would be even less reason to pass a separate instance to
> the constructor.  :-)

In C++0x, all allocators are not equivalent.  That weasel wording has
been removed.  Allocators of the same type can compare unequal and an
implementation is required to honor that.

>
> >From what I understand, the current standard allows implementations to
>
> make this assumption, but encourages implementors to support non-equal
> instances. C++0x seems to (at least want to) require it.

Yes.

> So, what do I use the second constructor for - if the allocator
> instance is different, I have to copy the string data, so why an
> rvalue. If the allocator is equal, why pass a new instance?

In generic code, you may not know, a priori, whether the allocator of
the object being moved is the same as the allocator you want to use
for the object being created.  If they are equal, then the constructor
behaves like a move constructor.  If they are not equal, it behaves
like a copy constructor.  The guiding principle here is that every
constructor must have a variant that takes an allocator so that
generic code can always control the memory allocation for objects it
creates.

- Pablo Halpern

[overquoting deleted -- mod/jad]

--
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@netlab.cs.rpi.edu]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: "Leigh Johnston" <leigh@i42.co.uk>
Date: Wed, 23 Sep 2009 13:15:15 CST
Raw View
If allocator instances no longer have to be equivalent how would you
implement std::list::splice?  Will std::list now have to compare allocators
to determine if splice is a straight node pointer change or a node
copy/delete operation?

/Leigh

"Pablo Halpern" <phalpern@halpernwightsoftware.com> wrote in message
news:8f526a2a-0afc-4656-b8de-92e9ebc9d4a7@d23g2000vbm.googlegroups.com...
> On Sep 22, 7:34 pm, "Bo Persson" <b...@gmb.dk> wrote:
>> Leigh Johnston wrote:
>> > All instances of an allocator have to be equivalent so there is
>> > nothing to compare.
>>
>> Then there would be even less reason to pass a separate instance to
>> the constructor.  :-)
>
> In C++0x, all allocators are not equivalent.  That weasel wording has
> been removed.  Allocators of the same type can compare unequal and an
> implementation is required to honor that.
>
>>
>> >From what I understand, the current standard allows implementations to
>>
>> make this assumption, but encourages implementors to support non-equal
>> instances. C++0x seems to (at least want to) require it.
>
> Yes.
>
>> So, what do I use the second constructor for - if the allocator
>> instance is different, I have to copy the string data, so why an
>> rvalue. If the allocator is equal, why pass a new instance?
>
> In generic code, you may not know, a priori, whether the allocator of
> the object being moved is the same as the allocator you want to use
> for the object being created.  If they are equal, then the constructor
> behaves like a move constructor.  If they are not equal, it behaves
> like a copy constructor.  The guiding principle here is that every
> constructor must have a variant that takes an allocator so that
> generic code can always control the memory allocation for objects it
> creates.
>
> - Pablo Halpern
>
> [overquoting deleted -- mod/jad]
>
> --
> [ comp.std.c++ is moderated.  To submit articles, try just posting with ]
> [ your news-reader.  If that fails, use mailto:std-c++@netlab.cs.rpi.edu]
> [              --- Please see the FAQ before posting. ---               ]
> [ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]
>


--
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@netlab.cs.rpi.edu]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: Tony <gottlobfrege@gmail.com>
Date: Wed, 23 Sep 2009 13:33:35 CST
Raw View
Bo Persson wrote:
> I have a hard time finding a use case for the second of these
> constructors:
>
> basic_string(basic_string&& str);
> basic_string(basic_string&&, const Allocator&);
>
> The first one will aquire all its contents from the str parameter,
> including str's allocator.
>
> But, if I find a need to pass a separate allocator instance to the
> constructor (second case), isn't it highly likely that this allocator
> will compare unequal to str's allocator? Why else would I need a
> different one?
>
> In they compare unequal, I believe we need to allocate a new string
> buffer and copy all the characters over. So what is the advantage of
> having an rvalue reference here?
>
>
> Bo Persson
>
>
>

Maybe for completeness? ie making it easier for generic code?
Of course that just moves the problem down one level:  instead of the
caller checking whether the allocators are equal (does caller have
access to that?) the impl will need to check.

Is the constructor expected to check the allocators and only copy when
necessary?  Or is that just quality-of-implementation?

Tony

--
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@netlab.cs.rpi.edu]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: Pete Becker <pete@versatilecoding.com>
Date: Wed, 23 Sep 2009 14:21:47 CST
Raw View
Leigh Johnston wrote:

> If allocator instances no longer have to be equivalent how would you
> implement std::list::splice?
>

Carefully.

 Will std::list now have to compare allocators
> to determine if splice is a straight node pointer change or a node
> copy/delete operation?
>
>
Yes.

--
 Pete
Roundhouse Consulting, Ltd. (www.versatilecoding.com) Author of
"The Standard C++ Library Extensions: a Tutorial and Reference"
(www.petebecker.com/tr1book)

[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use
mailto:std-c++@netlab.cs.rpi.edu<std-c%2B%2B@netlab.cs.rpi.edu>
]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: Pablo Halpern <phalpern@halpernwightsoftware.com>
Date: Thu, 24 Sep 2009 03:51:45 CST
Raw View
On Sep 23, 3:33 pm, Tony <gottlobfr...@gmail.com> wrote:
> Bo Persson wrote:
> > I have a hard time finding a use case for the second of these
> > constructors:
>
> > basic_string(basic_string&& str);
> > basic_string(basic_string&&, const Allocator&);
>
> > The first one will aquire all its contents from the str parameter,
> > including str's allocator.
>
> > But, if I find a need to pass a separate allocator instance to the
> > constructor (second case), isn't it highly likely that this allocator
> > will compare unequal to str's allocator? Why else would I need a
> > different one?
>
> > In they compare unequal, I believe we need to allocate a new string
> > buffer and copy all the characters over. So what is the advantage of
> > having an rvalue reference here?
>
> > Bo Persson
>
> Maybe for completeness? ie making it easier for generic code?
> Of course that just moves the problem down one level:  instead of the
> caller checking whether the allocators are equal (does caller have
> access to that?) the impl will need to check.

Yes, but since this is a constructor, the caller doesn't really have
the opportunity to check.  You can't choose to call one of two
different constructors based on a run-time value.  The only place
where this test makes sense is within the constructor itself.

> Is the constructor expected to check the allocators and only copy when
> necessary?  Or is that just quality-of-implementation?

It is required that the implementation check the allocators and copy
only when necessary.

- Pablo


--
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@netlab.cs.rpi.edu]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: Pablo Halpern <phalpern@halpernwightsoftware.com>
Date: Thu, 24 Sep 2009 03:50:49 CST
Raw View
On Sep 23, 4:21 pm, Pete Becker <p...@versatilecoding.com> wrote:
> Leigh Johnston wrote:
> > If allocator instances no longer have to be equivalent how would you
> > implement std::list::splice?
>
> Carefully.
>
>  Will std::list now have to compare allocators> to determine if splice is a straight node pointer change or a node
> > copy/delete operation?
>
> Yes.

No. If the allocators don't compare equal, then list::splice results
in undefined behavior.  We considered the use cases and decided that
splicing together lists of uncertain provenance is not something we
need to support.  Splice should always be a constant-time operation
and should never throw an exception.  If the client code cannot ensure
that the allocators are equal, then it cannot use splice safely.  A
reasonable implementation will assert that the allocators are equal
(in a debug build), thus catching the error.  If we tried to do
something cute behind the programmer's back, the logic error would
cause a silent loss of performance.

- Pablo


--
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@netlab.cs.rpi.edu]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: Pete Becker <pete@versatilecoding.com>
Date: Thu, 24 Sep 2009 13:37:00 CST
Raw View
Pablo Halpern wrote:
> On Sep 23, 4:21 pm, Pete Becker <p...@versatilecoding.com> wrote:
>> Leigh Johnston wrote:
>>> If allocator instances no longer have to be equivalent how would you
>>> implement std::list::splice?
>> Carefully.
>>
>>  Will std::list now have to compare allocators> to determine if splice is a straight node pointer change or a node
>>> copy/delete operation?
>> Yes.
>
> No. If the allocators don't compare equal, then list::splice results
> in undefined behavior.

Agreed. Answered too quickly.

--
   Pete
Roundhouse Consulting, Ltd. (www.versatilecoding.com) Author of
"The Standard C++ Library Extensions: a Tutorial and Reference"
(www.petebecker.com/tr1book)

[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@netlab.cs.rpi.edu]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]