[swap] How to override swap now?
I notice that Boost now has it's own boost::swap and that it has had recent trouble before the 1.36 release. How should a user/developer like me implement a custom swap so that users get the benefit of my::swap, then boost::swap, and finally std::swap without putting too much burden on my user. So I have three questions. (1) How should user-code use boost:swap? (2) How should boost-developers use boost::swap()? (3) How should non-boost-developers provide swap()? Consider my motivating (to me) example... Let's say I have a move library that works, hypothetically. namespace my { // These are defined and actually work, hypothetically. template <class T> struct is_moveable; template <class T> struct move_from { }; template <class T>T& move(T& x); template <class T> void swap(T& x, T& y) { T tmp = move(x); x = move(y); y = move(tmp); } // swap } // namespace my If the user does this... using namespace std; using namespace boost; using namespace my; And then somewhere in his code... HisType a = MakeA(); HisType b = MakeB(); swap(a, b); // Unqualified? Or should the user specify a namespace? Which one? What I wish would happen would be... If the user has his own swap(HisType, HisType) invoke that. Otherwise, if HisType.swap() exists, then use that. Otherwise, use my::swap() if its "better" than boost::swap Otherwise, use boost::swap(), if its "better" than std::swap Otherwise, just use std::swap(). Sorry about all the ambiguity. But that's the real problem, isn't it? terry
Terry G wrote:
I notice that Boost now has it's own boost::swap and that it has had recent trouble before the 1.36 release.
Please note: the swap utility from http://svn.boost.org/svn/boost/trunk/boost/utility/swap.hpp isn't yet part of any Boost release. I hope it will be included with the 1.37 release, though. Are you referring to some particular trouble? We had to work around a few issues recently, but the unit tests are doing well, these days: http://www.boost.org/development/tests/trunk/developer/utility-swap_.html
(1) How should user-code use boost:swap? (2) How should boost-developers use boost::swap()? (3) How should non-boost-developers provide swap()?
The preferred way to call the boost::swap utility is by having it /qualified/ by its namespace (boost): UserType a, b; boost::swap(a, b); The boost::swap utility is customizable for user type, by providing a custom swap within the namespace of the user type and/or by specializing std::swap for that particular type. Boost developers should just provide a custom boost::swap overload for their Boost types, whenever necessary, as they always did.
Consider my motivating (to me) example...
namespace my { template <class T> void swap(T& x, T& y) { } // swap } // namespace my
If the user does this...
using namespace std; using namespace boost; using namespace my;
And then somewhere in his code...
HisType a = MakeA(); HisType b = MakeB(); swap(a, b);
Won't compile, as it never did. The boost::swap utility won't solve the ambiguity between my::swap and std::swap.
What I wish would happen would be...
If the user has his own swap(HisType, HisType) invoke that. Otherwise, if HisType.swap() exists, then use that. Otherwise, use my::swap() if its "better" than boost::swap Otherwise, use boost::swap(), if its "better" than std::swap Otherwise, just use std::swap().
I'm sorry. The boost::swap utility just wraps the idiomatic "using std::swap; swap(a,b);". And while doing so, it provides a workaround for various compiler bugs regarding argument-dependent lookup. As an extra, it also supports swapping arrays. So the user should still provide a non-member swap function, whenever she provides a swap member function for her class. As is generally recommended. (E.g., Scott Meyers, Effective C++ Third Edition, Item 25: "Consider support for a non-throwing swap".) HTH, -- Niels Dekker http://www.xs4all.nl/~nd/dekkerware Scientific programmer at LKEB, Leiden University Medical Center
participants (2)
-
Niels Dekker - mail address until 2008-12-31
-
Terry G