Topic: Whence swap?
Author: nagle@animats.com (John Nagle)
Date: Sun, 25 Jul 2004 19:10:05 GMT Raw View
David Abrahams wrote:
> nagle@animats.com (John Nagle) wrote in message news:<epcMc.440$2o1.306@newssvr27.news.prodigy.com>...
>
>
>> This has a bit more code to make it actually do something.
>>The "owned" objects have a value, and swapping two "owned"
>>objects swaps their values and their ownership, while
>>maintaining the single-owner invariant.
>
>
> OK, so that swaps the owned objects but from the POV of their owners,
> the values are stable.
No, the values are swapped, too. Run the program.
John Nagle
---
[ 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.jamesd.demon.co.uk/csc/faq.html ]
Author: dave@boost-consulting.com (David Abrahams)
Date: Mon, 26 Jul 2004 00:39:39 GMT Raw View
dave@boost-consulting.com (David Abrahams) wrote in message news:<8a638f47.0407240609.4fca957@posting.google.com>...
> nagle@animats.com (John Nagle) wrote in message news:<epcMc.440$2o1.306@newssvr27.news.prodigy.com>...
>
> > This has a bit more code to make it actually do something.
> > The "owned" objects have a value, and swapping two "owned"
> > objects swaps their values and their ownership, while
> > maintaining the single-owner invariant.
>
> OK, so that swaps the owned objects but from the POV of their owners,
> the values are stable.
>
> > But these "owned" objects are not copyable, moveable,
> > or assignable.
> >
> > >>"Owned" objects always have exactly one owner. "move" would break
> > >>that constraint, so "move" is not meaningful for this class.
> > >>"swap", though, is valid.
>
> It's still not swap. Swap doesn't have side-effects outside the
> objects it's operating on, and any two "references" to the swapped
> objects should see the effects of the swap in the same way. You might
> get around that by claiming that the "owner" objects are part of the
> "owned" objects, but that's a bit perverse considering that creating
> the owned objects doesn't cause the owners to be created.
That said, I think I see your point -- a non-destructive move imposes
some requirements that swap does not. For example, that there can be
more than two instances of the type at the same time. Destructive
move imposes the constraint that there are at least three possible
addresses for an object... so if you break it down far enough it
begins to look like no operations are more fundamental than any
others. I wonder if that's true?
--
Dave Abrahams
Boost Consulting
http://www.boost-consulting.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 ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: hinnant@metrowerks.com (Howard Hinnant)
Date: Thu, 22 Jul 2004 02:23:15 GMT Raw View
In article <cdh1bp$ae6$1@swifty.westend.com>,
daniel.frey@aixigo.de (Daniel Frey) wrote:
> But if you consider the above to be the right direction, that is
> mandating user defined swap() functions to be implemented with the right
> semantics, I suggest you think about making std::swap an ADL-function in
> general:
>
> namespace std
> {
> namespace detail
> {
> template< typename T > void swap( T& lhs, T& rhs )
> {
> // Old implementation of std::swap() goes here...
> }
> }
>
> template< typename T > void swap( T& lhs, T& rhs )
> {
> using detail::swap;
> swap( lhs, rhs );
> }
> }
>
> No need for the above mentioned idiom [using std::swap; swap(...);]
> anymore. :)
I think this is a great suggestion! :-)
-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.jamesd.demon.co.uk/csc/faq.html ]
Author: dave@boost-consulting.com (David Abrahams)
Date: Thu, 22 Jul 2004 02:24:20 GMT Raw View
nagle@animats.com (John Nagle) writes:
> David Abrahams wrote:
>> nagle@animats.com (John Nagle) writes:
>>
>>>David Abrahams wrote:
>>>
>>>>nagle@animats.com (John Nagle) writes:
>>>>The real primitive is "move".
>>>
>>> I'd intended to say something about move semantics, but
>>>the topic discussed "swap".
>> But move really is more primitive. You can always implement swap in
>> terms of move.
>
> Wrong. Consider a simple single-owner relationship using
> references.
>
> class Owned; // forward
> class Owner {
> Owned* m_owned;
> public:
> Owner() { m_owned = new Owned(*this); }
> Owned& GetOwned() { return(m_owned); }
> };
>
> class Owned {
> Owner& m_owner;
> public:
> Owned(Owner& initialowner) // must have owner at all times
> { m_owner = initialowner; }
> void swap(Owned& other) // exchange ownership
> { Owner& temp = m_owner;
> m_owner = other.m_owner;
> other.m_owner = temp;
> }
> };
>
> ...
> Owner owner1, owner2;
> owner1.GetOwned().swap(owner2.GetOwned()); // swap ownership
I _think_ that's an amusing but misleading example. I can't tell,
though, because of the way you're using references (they don't reseat)
and a few other glaring bugs. I'm going to assume you meant something
like this instead -- please correct me if I'm wrong:
class Owned; // forward
class Owner
{
std::auto_ptr<Owned> m_owned;
public:
Owner() : m_owned(new Owned(*this)) {}
Owned& GetOwned() { *m_owned; }
};
class Owned
{
Owner* m_owner;
OtherData m_other;
public:
Owned(Owner& initialowner) // must have owner at all times
{ m_owner = &initialowner; }
friend void swap(Owned& o1, Owned& o2)
{
std::swap(o1.m_owner,o2.m_owner); // exchange ownership
// no need to exchange other data; we just reseated the
// Owned node's location in the structure.
}
};
...
Owner owner1, owner2;
swap(owner1.GetOwned(),owner2.GetOwned()); // swap ownership
To see why it's misleading, just consider what happens when you try to
sort a sequence of Owned objects and sort uses swap. It just messes
with their owner relationships and doesn't sort them at all. This is
not your fathers swapmobile! It isn't swap at all -- it just looks a
little bit like swap and happens to have the same name, but the
semantics are all wrong.
> "Owned" objects always have exactly one owner. "move" would break
> that constraint, so "move" is not meaningful for this class.
> "swap", though, is valid.
Despite the invalidity of your example, I'm still interested in
why/how you think move would break the constraint.
--
Dave Abrahams
Boost Consulting
http://www.boost-consulting.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 ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: hinnant@metrowerks.com (Howard Hinnant)
Date: Thu, 22 Jul 2004 02:24:45 GMT Raw View
In article <2m18dtFhp60nU1@uni-berlin.de>,
SeeWebsiteForEmail@moderncppdesign.com ("Andrei Alexandrescu (See
Website for Email)") wrote:
> "Howard Hinnant" <hinnant@metrowerks.com> wrote in message
> news:hinnant-B42471.11413118072004@syrcnyrdrs-02-ge0.nyroc.rr.com...
> > If you're an author of non-std generic code that wants to use swap, do
> > so like:
> >
> > template <class T>
> > void foo(T& t1, T& t2)
> > {
> > using std::swap;
> > swap(t1, t2);
> > }
>
> Does your implementation of the standard library use that idiom when
> swapping stuff internally? Would that be a standard-compliant way of doing
> things?
Essentially yes, Metrowerks uses this idiom. Of course if you know
you're already in namespace std, there's no need to put the using
declaration in there.
The solution is not standard conforming. However as soon as issues 225,
226 and 229 officially become part of the standard, it will be standard
conforming. These issues currently have status WP which means:
> The proposed resolution has not been accepted as a Technical Corrigendum,
> but the full WG21 committee has voted to apply the Defect Report's Proposed
> Resolution to the working paper.
I'm willing to take the conformance hit in the interim, in exchange for
happier customers (e.g. sort is fast even with a heavy My::UserType if
My::swap(UserType&, UserType&) exists).
-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.jamesd.demon.co.uk/csc/faq.html ]
Author: daniel.frey@aixigo.de (Daniel Frey)
Date: Fri, 23 Jul 2004 16:12:09 GMT Raw View
David Abrahams wrote:
> You can break this by defining
>=20
> template <class T>
> void swap(T&,T&);
>=20
> in your class' own namespace, [...]
The more I think about this, the less I understand why this is a=20
problem. The only problem I see is, when one creates an infinite loop by=20
defining his own swap() which calls std::swap() which in turn calls the=20
same user defined swap() again, etc. For your example, I don't see how=20
it breaks anything by the pure existence of such a function. Could you=20
please elaborate?
Regards, Daniel
--=20
Daniel Frey
aixigo AG - financial solutions & technology
Schlo=DF-Rahe-Stra=DFe 15, 52072 Aachen, Germany
fon: +49 (0)241 936737-42, fax: +49 (0)241 936737-99
eMail: daniel.frey@aixigo.de, web: http://www.aixigo.de
The hacks that we write today become the bugs of tomorrow.
---
[ 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.jamesd.demon.co.uk/csc/faq.html ]
Author: nagle@animats.com (John Nagle)
Date: Fri, 23 Jul 2004 20:55:41 GMT Raw View
David Abrahams wrote:
> nagle@animats.com (John Nagle) writes:
>
>
>>David Abrahams wrote:
>>
>>>nagle@animats.com (John Nagle) writes:
>>>
>>>
>>>>David Abrahams wrote:
>>>>
>>>>
>>>>>nagle@animats.com (John Nagle) writes:
>>>>>The real primitive is "move".
>>>>
>>>> I'd intended to say something about move semantics, but
>>>>the topic discussed "swap".
>>>
>>>But move really is more primitive. You can always implement swap in
>>>terms of move.
>>
>> Wrong. Consider a simple single-owner relationship using
>>references.
This version compiles and runs:
====
#include <assert.h>
#include <stdio.h>
class Owned; // forward
class Owner {
Owned* m_owned;
public:
Owner();
Owned& GetOwned() { return(*m_owned); }
void SetOwned(Owned& newowns)
{
m_owned = &newowns;
}
};
class Owned {
Owner& m_owner;
int m_value; // the content of this object
public:
Owned(Owner& initialowner) // must have owner at all times
: m_owner(initialowner), m_value(0) {}
void swap(Owned& other)
{ assert(&(m_owner.GetOwned()) == this); // invariant
assert(&(other.m_owner.GetOwned()) == other);
Owner& temp = m_owner; // swap ownership
m_owner = other.m_owner;
other.m_owner = temp;
m_owner.SetOwned(*this);// update owning object
other.m_owner.SetOwned(other);
int vtemp = m_value; // swap content
m_value = other.m_value;
other.m_value = vtemp;
assert(&(m_owner.GetOwned()) == this); // invariant
assert(&(other.m_owner.GetOwned()) == other);
}
int GetValue() const { return(m_value); }
void SetValue(int val) { m_value = val; }
};
inline Owner::Owner() { m_owned = new Owned(*this); }
void ownertest()
{
Owner owner1, owner2;
owner1.GetOwned().SetValue(1); // set object content
owner2.GetOwned().SetValue(2);
owner1.GetOwned().swap(owner2.GetOwned()); // swap objects
printf("Owner 1's owned object value: %d\n",
owner1.GetOwned().GetValue());
printf("Owner 2's owned object value: %d\n",
owner2.GetOwned().GetValue());
}
====
This has a bit more code to make it actually do something.
The "owned" objects have a value, and swapping two "owned"
objects swaps their values and their ownership, while
maintaining the single-owner invariant.
But these "owned" objects are not copyable, moveable,
or assignable.
>>"Owned" objects always have exactly one owner. "move" would break
>>that constraint, so "move" is not meaningful for this class.
>>"swap", though, is valid.
John Nagle
Animats
---
[ 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.jamesd.demon.co.uk/csc/faq.html ]
Author: hinnant@metrowerks.com (Howard Hinnant)
Date: Fri, 23 Jul 2004 22:47:19 GMT Raw View
In article <epcMc.440$2o1.306@newssvr27.news.prodigy.com>,
nagle@animats.com (John Nagle) wrote:
> But these "owned" objects are not copyable, moveable,
> or assignable.
<nit> "movable" is too general of a term. I believe you mean that they
are not move constructible, in a non-destructive fashion. I.e. you
can't:
Owner owner2(move(owner1));
by the semantics of N1377.
If we had destructive move construction (not proposed by N1377), then
Owner could do that. Also Owner is move assignable (which could be
implemented simply with swap).
Just trying to straighten out the "movable" terminology.
-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.jamesd.demon.co.uk/csc/faq.html ]
Author: dave@boost-consulting.com (David Abrahams)
Date: Sat, 24 Jul 2004 19:32:34 GMT Raw View
nagle@animats.com (John Nagle) wrote in message news:<epcMc.440$2o1.306@newssvr27.news.prodigy.com>...
> This has a bit more code to make it actually do something.
> The "owned" objects have a value, and swapping two "owned"
> objects swaps their values and their ownership, while
> maintaining the single-owner invariant.
OK, so that swaps the owned objects but from the POV of their owners,
the values are stable.
> But these "owned" objects are not copyable, moveable,
> or assignable.
>
> >>"Owned" objects always have exactly one owner. "move" would break
> >>that constraint, so "move" is not meaningful for this class.
> >>"swap", though, is valid.
It's still not swap. Swap doesn't have side-effects outside the
objects it's operating on, and any two "references" to the swapped
objects should see the effects of the swap in the same way. You might
get around that by claiming that the "owner" objects are part of the
"owned" objects, but that's a bit perverse considering that creating
the owned objects doesn't cause the owners to be created.
--
Dave Abrahams
Boost Consulting
http://www.boost-consulting.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 ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: Usenet@aristeia.com (Scott Meyers)
Date: Sat, 17 Jul 2004 04:55:04 +0000 (UTC) Raw View
As far as I know, the STL marked the introduction of a nonthrowing "swap"
into C++, and since then swap has become the cornerstone of idioms such as
copy-and-swap for achieving the strong exception safety guarantee. Does
anybody know why swap was introduced into the STL in the first place? My
understanding is that it's not mandated as part of the implementation of
any algorithm (e.g., sort need not call swap), so why was swap designed in?
Was it put there specifically as a mechanism for writing strongly exception
safe functions, or was that just something peole later figured out it could
be used for?
All insights appreciated,
Scott
---
[ 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.jamesd.demon.co.uk/csc/faq.html ]
Author: petebecker@acm.org (Pete Becker)
Date: Sat, 17 Jul 2004 15:15:04 +0000 (UTC) Raw View
Scott Meyers wrote:
>
> As far as I know, the STL marked the introduction of a nonthrowing "swap"
> into C++, and since then swap has become the cornerstone of idioms such as
> copy-and-swap for achieving the strong exception safety guarantee. Does
> anybody know why swap was introduced into the STL in the first place? My
> understanding is that it's not mandated as part of the implementation of
> any algorithm (e.g., sort need not call swap), so why was swap designed in?
> Was it put there specifically as a mechanism for writing strongly exception
> safe functions, or was that just something peole later figured out it could
> be used for?
>
It can be more efficient than doing multiple copies of an entire object.
Especially for large containers, where swap can exchange a bit of
bookkeeping information and a couple of pointers rather than copy all of
the stored objects.
--
Pete Becker
Dinkumware, Ltd. (http://www.dinkumware.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 ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: dave@boost-consulting.com (David Abrahams)
Date: Sat, 17 Jul 2004 15:15:50 +0000 (UTC) Raw View
Usenet@aristeia.com (Scott Meyers) writes:
> As far as I know, the STL marked the introduction of a nonthrowing "swap"
> into C++
std::swap is not nonthrowing.
> and since then swap has become the cornerstone of
..oversold, often inefficient ;-)...
> idioms such as copy-and-swap for achieving the strong exception
> safety guarantee.
and which others?
> Does anybody know why swap was introduced into the STL in the first
> place?
I'm guessing, here: for efficient sorting.
> My understanding is that it's not mandated as part of the
> implementation of any algorithm (e.g., sort need not call swap), so
> why was swap designed in?
Because if sort *does* call swap, and if for something like
std::string there's an efficient overload, you can efficiently sort
collections of strings. Otherwise the sort still calls swap and its
default implementation just does the copy construction and assignments
that would have happened if sort was swapping "manually" anyway.
IOW, swap provides a customization point for sorting.
> Was it put there specifically as a
> mechanism for writing strongly exception safe functions
Definitely not. I just pointed out that we could easily give some
functions the strong guarantee via copy/swap (now sometimes I wish I
hadn't) -- swap had already been there for a long time.
> or was that just something peole later figured out it could be used
> for?
The latter.
--
Dave Abrahams
Boost Consulting
http://www.boost-consulting.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 ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: ark@acm.org ("Andrew Koenig")
Date: Sat, 17 Jul 2004 16:43:27 +0000 (UTC) Raw View
"Scott Meyers" <Usenet@aristeia.com> wrote in message
news:MPG.1b61fd662d3812a2989779@news.hevanet.com...
> As far as I know, the STL marked the introduction of a nonthrowing "swap"
> into C++, and since then swap has become the cornerstone of idioms such as
> copy-and-swap for achieving the strong exception safety guarantee. Does
> anybody know why swap was introduced into the STL in the first place? My
> understanding is that it's not mandated as part of the implementation of
> any algorithm (e.g., sort need not call swap), so why was swap designed
in?
Because it is usually possible to swap the contents of two n-element
containers in O(1) time, but swapping the elements would require O(n). This
difference is significant for algorithms such as sort and reverse that
depend on swapping to do their work.
---
[ 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.jamesd.demon.co.uk/csc/faq.html ]
Author: Usenet@aristeia.com (Scott Meyers)
Date: Sun, 18 Jul 2004 00:13:04 +0000 (UTC) Raw View
On Sat, 17 Jul 2004 16:43:27 +0000 (UTC), Andrew Koenig wrote:
> Because it is usually possible to swap the contents of two n-element
> containers in O(1) time, but swapping the elements would require O(n). This
> difference is significant for algorithms such as sort and reverse that
> depend on swapping to do their work.
But the sorting algorithms are not required to call swap. Reverse is
required to call iter_swap, but iter_swap is not required to call swap, and
neither Comeau 4.3.3 nor g++ 3.2 (mingw) do.
If swap was introduced to facilitate swapping-based algorithms, why is swap
not mentioned wrt those algorithms in the standard?
Thanks,
Scott
---
[ 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.jamesd.demon.co.uk/csc/faq.html ]
Author: kuyper@wizard.net (James Kuyper)
Date: Sun, 18 Jul 2004 05:33:47 +0000 (UTC) Raw View
Usenet@aristeia.com (Scott Meyers) wrote in message news:<MPG.1b61fd662d3812a2989779@news.hevanet.com>...
> As far as I know, the STL marked the introduction of a nonthrowing "swap"
> into C++, and since then swap has become the cornerstone of idioms such as
> copy-and-swap for achieving the strong exception safety guarantee. Does
> anybody know why swap was introduced into the STL in the first place? My
> understanding is that it's not mandated as part of the implementation of
> any algorithm (e.g., sort need not call swap), so why was swap designed in?
For containers, the effects of a.swap(b) are given as swap(a,b).
> Was it put there specifically as a mechanism for writing strongly exception
> safe functions, or was that just something peole later figured out it could
> be used for?
I can't claim any historical knowledge of this issue. However, I
understand that there's a naive implementation of swap<T>() that will
work for any Assignable type. On the other hand, for many particular
types, such as handle types, swap<T>() can be specialized to use a
much more efficient approach. The swap<T>() template allows you to
write code that uses the naive implementation for most types, and the
more efficient implementation that is provided by the specializations,
if there are any, without you having to even be aware of the
distinction.
I don't know if that's the main purpose, but I think it's at least
part of the purpose.
---
[ 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.jamesd.demon.co.uk/csc/faq.html ]
Author: dave@boost-consulting.com (David Abrahams)
Date: Sun, 18 Jul 2004 05:33:57 +0000 (UTC) Raw View
Usenet@aristeia.com (Scott Meyers) writes:
> On Sat, 17 Jul 2004 16:43:27 +0000 (UTC), Andrew Koenig wrote:
>> Because it is usually possible to swap the contents of two n-element
>> containers in O(1) time, but swapping the elements would require O(n). This
>> difference is significant for algorithms such as sort and reverse that
>> depend on swapping to do their work.
>
> But the sorting algorithms are not required to call swap.
No, but they're allowed to. They were not allowed to call it without
qualification before
http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#226 was
resolved by
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2003/n1523.htm but
that doesn't change anything for sorting sequences of standard
containers. Those will still be swapped by std::swap.
> Reverse is required to call iter_swap, but iter_swap is not required
> to call swap
It is since
http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#187 ;-)
> and neither Comeau 4.3.3 nor g++ 3.2 (mingw) do.
>
> If swap was introduced to facilitate swapping-based algorithms, why
> is swap not mentioned wrt those algorithms in the standard?
Because the standard is generally designed to *allow* optimizations
but not *mandate* implementation details, so as not to prevent
implementors from finding new, innovative optimizations.
--
Dave Abrahams
Boost Consulting
http://www.boost-consulting.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 ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: Usenet@aristeia.com (Scott Meyers)
Date: Sun, 18 Jul 2004 09:20:35 +0000 (UTC) Raw View
On Sun, 18 Jul 2004 05:33:57 +0000 (UTC), David Abrahams wrote:
> No, but they're allowed to. They were not allowed to call it without
> qualification before
> http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#226 was
> resolved by
> http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2003/n1523.htm but
> that doesn't change anything for sorting sequences of standard
> containers. Those will still be swapped by std::swap.
Thanks for the URLs. I'm now confused. Suppose I'm the author of a class
Widget, and I want to optimize Widget swapping. What do I do?
1 Define the member functions Widget::swap?
2 Define the non-member function swap(Widget&, Widget&)?
3 Define the specialization std::swap<Widget>(Widget&, Widget&)?
Until your post, I would have guessed that I should definitely do 3, and it
would probably be a nice idea to do 1, too. Now I'm beginning to think
that I'm supposed to do 2 instead of 3...
Now suppose that Widget is a template. I can still do 1, and I can do 2 by
defining swap as a template. But I'm not allowed to do 3 at all, because I
can't add partial specializations to std. At least I don't think I can.
So what do I do?
In summary, what is a class or class template author supposed to do to
offer optimized swapping that will be automatically taken advantage of by
the standard and other libraries?
Thanks,
Scott
---
[ 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.jamesd.demon.co.uk/csc/faq.html ]
Author: nagle@animats.com (John Nagle)
Date: Sun, 18 Jul 2004 09:21:24 +0000 (UTC) Raw View
===================================== MODERATOR'S COMMENT:
A. Yes.
Q. Is top-posting discouraged in this newsgroup?
===================================== END OF MODERATOR'S COMMENT
In some ways, "swap" is more primitive than assignment.
Objects with backpointers, for example, can be swapped
but not copied. All objects which can be copied can
be swapped, but the reverse is not always true.
Arguably, objects going into collections should be
swapped in, rather than copied in. Then you could
have collections of objects with backpointers.
Collections of auto_ptr would work, too.
John Nagle
Animats
Scott Meyers wrote:
> As far as I know, the STL marked the introduction of a nonthrowing "swap"
> into C++, and since then swap has become the cornerstone of idioms such as
> copy-and-swap for achieving the strong exception safety guarantee. Does
> anybody know why swap was introduced into the STL in the first place?
---
[ 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.jamesd.demon.co.uk/csc/faq.html ]
Author: hinnant@metrowerks.com (Howard Hinnant)
Date: Mon, 19 Jul 2004 00:11:09 +0000 (UTC) Raw View
In article <MPG.1b63b85dd21c460698977f@news.hevanet.com>,
Usenet@aristeia.com (Scott Meyers) wrote:
> On Sun, 18 Jul 2004 05:33:57 +0000 (UTC), David Abrahams wrote:
> > No, but they're allowed to. They were not allowed to call it without
> > qualification before
> > http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#226 was
> > resolved by
> > http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2003/n1523.htm but
> > that doesn't change anything for sorting sequences of standard
> > containers. Those will still be swapped by std::swap.
>
> Thanks for the URLs. I'm now confused. Suppose I'm the author of a class
> Widget, and I want to optimize Widget swapping. What do I do?
>
> 1 Define the member functions Widget::swap?
> 2 Define the non-member function swap(Widget&, Widget&)?
> 3 Define the specialization std::swap<Widget>(Widget&, Widget&)?
>
> Until your post, I would have guessed that I should definitely do 3, and it
> would probably be a nice idea to do 1, too. Now I'm beginning to think
> that I'm supposed to do 2 instead of 3...
>
> Now suppose that Widget is a template. I can still do 1, and I can do 2 by
> defining swap as a template. But I'm not allowed to do 3 at all, because I
> can't add partial specializations to std. At least I don't think I can.
> So what do I do?
>
> In summary, what is a class or class template author supposed to do to
> offer optimized swapping that will be automatically taken advantage of by
> the standard and other libraries?
Do 2. If you want to additionally do 1 to help you implement 2, no
problem.
If you're an author of non-std generic code that wants to use swap, do
so like:
template <class T>
void foo(T& t1, T& t2)
{
using std::swap;
swap(t1, t2);
}
swap is a fundamental operation on a type, like copy. It belongs in the
type's interface.
Coming soon (I hope): Move is a fundamental operation on a type, like
copy and swap. It belongs in the type's interface.
-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.jamesd.demon.co.uk/csc/faq.html ]
Author: dave@boost-consulting.com (David Abrahams)
Date: Mon, 19 Jul 2004 00:11:53 +0000 (UTC) Raw View
Usenet@aristeia.com (Scott Meyers) writes:
> On Sun, 18 Jul 2004 05:33:57 +0000 (UTC), David Abrahams wrote:
>> No, but they're allowed to. They were not allowed to call it without
>> qualification before
>> http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#226 was
>> resolved by
>> http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2003/n1523.htm but
>> that doesn't change anything for sorting sequences of standard
>> containers. Those will still be swapped by std::swap.
>
> Thanks for the URLs. I'm now confused. Suppose I'm the author of a class
> Widget, and I want to optimize Widget swapping. What do I do?
>
> 1 Define the member functions Widget::swap?
#1 is irrelevant to generic code, since builtins don't have member
functions.
> 2 Define the non-member function swap(Widget&, Widget&)?
> 3 Define the specialization std::swap<Widget>(Widget&, Widget&)?
If you want your swap to be used in as many contexts as possible, you
should do #2 (in Widget's namespace) _and_ #3. You can of course
dispatch one to the other.
#3 will pick up std:: qualified calls to swap, and #2 will pick up
unqualified calls to swap. Doing #2 means you have to hope that the
author of those other libraries was cognizant of ADL and really
expects the "usual semantics" for swap(x,y).
> Until your post, I would have guessed that I should definitely do 3, and it
> would probably be a nice idea to do 1, too. Now I'm beginning to think
> that I'm supposed to do 2 instead of 3...
#2 is your best option once all libraries agree that swap means what
std:: says and it should be called without qualification. Until
then, it's #2 and #3.
> Now suppose that Widget is a template. I can still do 1, and I can do 2 by
> defining swap as a template. But I'm not allowed to do 3 at all
Right.
> because I can't add partial specializations to std.
Yes you can. But there's no partial specialization of function
templates.
> At least I don't think I can. So what do I do?
You do #2.
> In summary, what is a class or class template author supposed to do to
> offer optimized swapping that will be automatically taken advantage of by
> the standard and other libraries?
With the caveat that there are no guarantees that a (standard) library
implementation not written with the resolution to LWG#226 in mind will
ever use swap, you do #2/#3 for non-templates and #2 for templates.
In practice many people will probably just do #2 and call it "good
enough".
Cheers,
--
Dave Abrahams
Boost Consulting
http://www.boost-consulting.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 ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: dave@boost-consulting.com (David Abrahams)
Date: Mon, 19 Jul 2004 03:26:24 +0000 (UTC) Raw View
nagle@animats.com (John Nagle) writes:
> ===================================== MODERATOR'S COMMENT: A. Yes.
> Q. Is top-posting discouraged in this newsgroup?
>
>
> ===================================== END OF MODERATOR'S COMMENT
> In some ways, "swap" is more primitive than assignment.
The real primitive is "move".
> Objects with backpointers, for example, can be swapped
> but not copied. All objects which can be copied can
> be swapped,
I don't think so. A non-assignable but copyable object can't be
swapped.
> but the reverse is not always true.
> Arguably, objects going into collections should be
> swapped in, rather than copied in.
I think it'd be better not to try to swap const objects, don't you?
That seems like a pretty common case. Also, when inserting a new
object, there's nothing to swap with!
I'm pretty sure what you're looking for is "move construction". I'm
sure you've seen
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2002/n1377.htm,
though...?
--
Dave Abrahams
Boost Consulting
http://www.boost-consulting.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 ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: SeeWebsiteForEmail@moderncppdesign.com ("Andrei Alexandrescu (See Website for Email)")
Date: Mon, 19 Jul 2004 17:03:42 GMT Raw View
"Howard Hinnant" <hinnant@metrowerks.com> wrote in message
news:hinnant-B42471.11413118072004@syrcnyrdrs-02-ge0.nyroc.rr.com...
> If you're an author of non-std generic code that wants to use swap, do
> so like:
>
> template <class T>
> void foo(T& t1, T& t2)
> {
> using std::swap;
> swap(t1, t2);
> }
Does your implementation of the standard library use that idiom when
swapping stuff internally? Would that be a standard-compliant way of doing
things?
Andrei
---
[ 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.jamesd.demon.co.uk/csc/faq.html ]
Author: nagle@animats.com (John Nagle)
Date: Mon, 19 Jul 2004 17:03:45 GMT Raw View
David Abrahams wrote:
> nagle@animats.com (John Nagle) writes:
>
> The real primitive is "move".
I'd intended to say something about move semantics, but
the topic discussed "swap".
>
>>Objects with backpointers, for example, can be swapped
>>but not copied.
This is the real case when you need "swap".
> Also, when inserting a new
> object, there's nothing to swap with!
Arguably, you're swapping with an object constructed with the
default constructor.
> I'm pretty sure what you're looking for is "move construction". I'm
> sure you've seen
> http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2002/n1377.htm,
> though...?
That seems overly complicated. A simpler approach is that
these definitions should be available:
template <class T> T stl::swap(T& a, T& b)
{ T temp = a; a = b; b = temp; } // default, overrideable
template <class T> T stl::move(T& a, const T& b)
{ a = b; } // default implementation, overrideable
Insertion into collections should use "move", and some other operations
should use "swap" when appropriate. (Should resizing a vector
use "swap"?) Classes that don't define "swap" or "move" get the
existing assignment semantics, but classes that need it can
define either or both.
John Nagle
---
[ 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.jamesd.demon.co.uk/csc/faq.html ]
Author: daniel.frey@aixigo.de (Daniel Frey)
Date: Mon, 19 Jul 2004 18:02:12 GMT Raw View
Andrei Alexandrescu (See Website for Email) wrote:
> "Howard Hinnant" <hinnant@metrowerks.com> wrote in message
> news:hinnant-B42471.11413118072004@syrcnyrdrs-02-ge0.nyroc.rr.com...
>=20
>>If you're an author of non-std generic code that wants to use swap, do
>>so like:
>>
>>template <class T>
>>void foo(T& t1, T& t2)
>>{
>> using std::swap;
>> swap(t1, t2);
>>}
>=20
>=20
> Does your implementation of the standard library use that idiom when
> swapping stuff internally? Would that be a standard-compliant way of do=
ing
> things?
The standard doesn't put any requirements on functions called swap()=20
outside of namespace std, thus such an STL implementation cannot be=20
standard compliant. The user defined swap() could do anything it likes=20
(even nothing), although it's quite unlikely.
But if you consider the above to be the right direction, that is=20
mandating user defined swap() functions to be implemented with the right=20
semantics, I suggest you think about making std::swap an ADL-function in=20
general:
namespace std
{
namespace detail
{
template< typename T > void swap( T& lhs, T& rhs )
{
// Old implementation of std::swap() goes here...
}
}
template< typename T > void swap( T& lhs, T& rhs )
{
using detail::swap;
swap( lhs, rhs );
}
}
No need for the above mentioned idiom [using std::swap; swap(...);]=20
anymore. :)
Regards, Daniel
--=20
Daniel Frey
aixigo AG - financial solutions & technology
Schlo=DF-Rahe-Stra=DFe 15, 52072 Aachen, Germany
fon: +49 (0)241 936737-42, fax: +49 (0)241 936737-99
eMail: daniel.frey@aixigo.de, web: http://www.aixigo.de
---
[ 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.jamesd.demon.co.uk/csc/faq.html ]
Author: dave@boost-consulting.com (David Abrahams)
Date: Tue, 20 Jul 2004 06:04:17 GMT Raw View
nagle@animats.com (John Nagle) writes:
> David Abrahams wrote:
>> nagle@animats.com (John Nagle) writes:
>> The real primitive is "move".
>
> I'd intended to say something about move semantics, but
> the topic discussed "swap".
But move really is more primitive. You can always implement swap in
terms of move. If there's no specialized move for a class, the
semantics degenerate to the current swap using copy/assign.
>>>Objects with backpointers, for example, can be swapped
>>> but not copied.
>
> This is the real case when you need "swap".
>
>> Also, when inserting a new
>> object, there's nothing to swap with!
>
> Arguably, you're swapping with an object constructed with the
> default constructor.
Horrors! Now you want to require default-constructibility for
container elements? IMO that's silly. All that's required to do that
efficiently is move construction.
>> I'm pretty sure what you're looking for is "move construction". I'm
>> sure you've seen
>> http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2002/n1377.htm,
>> though...?
>
> That seems overly complicated.
>
> A simpler approach is that
> these definitions should be available:
>
> template <class T> T stl::swap(T& a, T& b)
> { T temp = a; a = b; b = temp; } // default, overrideable
>
> template <class T> T stl::move(T& a, const T& b)
> { a = b; } // default implementation, overrideable
>
> Insertion into collections should use "move", and some other operations
> should use "swap" when appropriate.
:-)
That complication you refer to is the difference between a
well-thought-out proposal and an off-the-cuff NG posting.
The proposal doesn't suggest removing swap (though it should be
redefined in terms of move) and it does contain a move() like the one
above, though with the opposite argument order.
What you're proposing doesn't account for all the wasted copies of
rvalues that we presently make in C++. Technically there *are* arcane
ways to avoid some of these copies, but they're ugly, nonportable in
practice, expert-level-only, nonuniform, and they don't scale well.
> (Should resizing a vector use "swap"?)
Not unless we're going to introduce a new default-constructibility
requirement on the elements!
> Classes that don't define "swap" or "move" get the
> existing assignment semantics, but classes that need it can
> define either or both.
Sheesh, it seems to me you ought to read n1377 again. So far you're
describing a weak version of what's there.
--
Dave Abrahams
Boost Consulting
http://www.boost-consulting.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 ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: dave@boost-consulting.com (David Abrahams)
Date: Tue, 20 Jul 2004 06:04:57 GMT Raw View
Very interesting. You can break this by defining
template <class T>
void swap(T&,T&);
in your class' own namespace, but any more-specific definition of swap
will not cause an ambiguity AFAICT. In fact, I know how to detect
whether there's a definition of swap that would be found via ADL, so
I'm pretty sure that problem can be resolved. I wonder if there are
any other problems lurking?
daniel.frey@aixigo.de (Daniel Frey) writes:
> Andrei Alexandrescu (See Website for Email) wrote:
>> "Howard Hinnant" <hinnant@metrowerks.com> wrote in message
>> news:hinnant-B42471.11413118072004@syrcnyrdrs-02-ge0.nyroc.rr.com...
>>=20
>>>If you're an author of non-std generic code that wants to use swap, do
>>>so like:
>>>
>>>template <class T>
>>>void foo(T& t1, T& t2)
>>>{
>>> using std::swap;
>>> swap(t1, t2);
>>>}
>> Does your implementation of the standard library use that idiom when
>> swapping stuff internally? Would that be a standard-compliant way of d=
oing
>> things?
>
> The standard doesn't put any requirements on functions called swap()
> outside of namespace std, thus such an STL implementation cannot be
> standard compliant. The user defined swap() could do anything it likes
> (even nothing), although it's quite unlikely.
>
> But if you consider the above to be the right direction, that is
> mandating user defined swap() functions to be implemented with the
> right semantics, I suggest you think about making std::swap an
> ADL-function in general:
>
> namespace std
> {
> namespace detail
> {
> template< typename T > void swap( T& lhs, T& rhs )
> {
> // Old implementation of std::swap() goes here...
> }
> }
>
> template< typename T > void swap( T& lhs, T& rhs )
> {
> using detail::swap;
> swap( lhs, rhs );
> }
> }
>
> No need for the above mentioned idiom [using std::swap; swap(...);]
> anymore. :)
>
> Regards, Daniel
>
> --=20
> Daniel Frey
>
> aixigo AG - financial solutions & technology
> Schlo=DF-Rahe-Stra=DFe 15, 52072 Aachen, Germany
> fon: +49 (0)241 936737-42, fax: +49 (0)241 936737-99
> eMail: daniel.frey@aixigo.de, web: http://www.aixigo.de
>
>
> ---
> [ 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.jamesd.demon.co.uk/csc/faq.html =
]
>
--=20
Dave Abrahams
Boost Consulting
http://www.boost-consulting.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 ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: vze2hb3b@verizon.net
Date: Tue, 20 Jul 2004 17:52:13 GMT Raw View
David Abrahams <dave@boost-consulting.com> wrote:
>
> Very interesting. You can break this by defining
>
> template <class T>
> void swap(T&,T&);
>
> in your class' own namespace, but any more-specific definition of swap
> will not cause an ambiguity AFAICT. In fact, I know how to detect
> whether there's a definition of swap that would be found via ADL, so
> I'm pretty sure that problem can be resolved. I wonder if there are
> any other problems lurking?
>
Please, excuse my ignorance, but what exactly ADL stands for? Google gives
me "Assertion Definition Language" which is probably not relevant to
this discussion.
Thank you,
Alexander
> daniel.frey@aixigo.de (Daniel Frey) writes:
>
>> Andrei Alexandrescu (See Website for Email) wrote:
>>> "Howard Hinnant" <hinnant@metrowerks.com> wrote in message
>>> news:hinnant-B42471.11413118072004@syrcnyrdrs-02-ge0.nyroc.rr.com...
>>>
>>>>If you're an author of non-std generic code that wants to use swap, do
>>>>so like:
>>>>
>>>>template <class T>
>>>>void foo(T& t1, T& t2)
>>>>{
>>>> using std::swap;
>>>> swap(t1, t2);
>>>>}
>>> Does your implementation of the standard library use that idiom when
>>> swapping stuff internally? Would that be a standard-compliant way of doing
>>> things?
>>
>> The standard doesn't put any requirements on functions called swap()
>> outside of namespace std, thus such an STL implementation cannot be
>> standard compliant. The user defined swap() could do anything it likes
>> (even nothing), although it's quite unlikely.
>>
>> But if you consider the above to be the right direction, that is
>> mandating user defined swap() functions to be implemented with the
>> right semantics, I suggest you think about making std::swap an
>> ADL-function in general:
>>
>> namespace std
>> {
>> namespace detail
>> {
>> template< typename T > void swap( T& lhs, T& rhs )
>> {
>> // Old implementation of std::swap() goes here...
>> }
>> }
>>
>> template< typename T > void swap( T& lhs, T& rhs )
>> {
>> using detail::swap;
>> swap( lhs, rhs );
>> }
>> }
>>
>> No need for the above mentioned idiom [using std::swap; swap(...);]
>> anymore. :)
>>
>> Regards, Daniel
>>
>> --
>> Daniel Frey
>>
>> aixigo AG - financial solutions & technology
>> Schlo?-Rahe-Stra?e 15, 52072 Aachen, Germany
>> fon: +49 (0)241 936737-42, fax: +49 (0)241 936737-99
>> eMail: daniel.frey@aixigo.de, web: http://www.aixigo.de
>>
>>
>> ---
>> [ 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.jamesd.demon.co.uk/csc/faq.html ]
>>
>
--
Aleksandr Morgulis
aleksandr.morgulis@verizon.net
---
[ 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.jamesd.demon.co.uk/csc/faq.html ]
Author: pjp@dinkumware.com ("P.J. Plauger")
Date: Tue, 20 Jul 2004 18:51:34 GMT Raw View
<vze2hb3b@verizon.net> wrote in message
news:0d9Lc.19775$gt1.7654@nwrddc02.gnilink.net...
> Please, excuse my ignorance, but what exactly ADL stands for? Google gives
> me "Assertion Definition Language" which is probably not relevant to
> this discussion.
Argument-dependent lookup. The namespace where each argument type is
defined becomes a candidate for hunting down a suitable function
overload. It was once known as Koenig Lookup, in honor of Andy Koenig's
first major hot patch for namespaces.
P.J. Plauger
Dinkumware, Ltd.
http://www.dinkumware.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 ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: daniel.frey@aixigo.de (Daniel Frey)
Date: Tue, 20 Jul 2004 18:51:43 GMT Raw View
vze2hb3b@verizon.net wrote:
> Please, excuse my ignorance, but what exactly ADL stands for? Google gi=
ves
> me "Assertion Definition Language" which is probably not relevant to
> this discussion.
ADL, in the context of the C++ programming language, stands for=20
"argument dependend lookup". The following link gives a nice=20
explanation: <http://semantics.org/once_weakly/ck30_adl.pdf>
Regards, Daniel
--=20
Daniel Frey
aixigo AG - financial solutions & technology
Schlo=DF-Rahe-Stra=DFe 15, 52072 Aachen, Germany
fon: +49 (0)241 936737-42, fax: +49 (0)241 936737-99
eMail: daniel.frey@aixigo.de, web: http://www.aixigo.de
---
[ 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.jamesd.demon.co.uk/csc/faq.html ]
Author: nagle@animats.com (John Nagle)
Date: Wed, 21 Jul 2004 14:29:26 GMT Raw View
David Abrahams wrote:
> nagle@animats.com (John Nagle) writes:
>
>
>>David Abrahams wrote:
>>
>>>nagle@animats.com (John Nagle) writes:
>>>The real primitive is "move".
>>
>> I'd intended to say something about move semantics, but
>>the topic discussed "swap".
>
>
> But move really is more primitive. You can always implement swap in
> terms of move.
Wrong. Consider a simple single-owner relationship using
references.
class Owned; // forward
class Owner {
Owned* m_owned;
public:
Owner() { m_owned = new Owned(*this); }
Owned& GetOwned() { return(m_owned); }
};
class Owned {
Owner& m_owner;
public:
Owned(Owner& initialowner) // must have owner at all times
{ m_owner = initialowner; }
void swap(Owned& other) // exchange ownership
{ Owner& temp = m_owner;
m_owner = other.m_owner;
other.m_owner = temp;
}
};
...
Owner owner1, owner2;
owner1.GetOwned().swap(owner2.GetOwned()); // swap ownership
"Owned" objects always have exactly one owner. "move" would break
that constraint, so "move" is not meaningful for this class.
"swap", though, is valid.
John Nagle
Animats
---
[ 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.jamesd.demon.co.uk/csc/faq.html ]