std::swap() vs boost::swap()
Boost classes that define a swap() member function usually also provide a global swap() function: namespace boost { class X { void swap(X &rhs); }; template<class T> void swap(X &lhs, X &rhs) { lhs.swap(rhs); } } Why is the global swap() function defined in namespace boost and not as a specialization of std::swap<>() in namespace std? Suppose I have a template function like the following: #include <algorithms> template <typename T> void do_something_and_swap(T &a, T &b) { // do something ... std::swap(a, b); } I want this template function to work with every type that is "swappable", but if I try to use it with boost::scoped_ptr<> the compiler fails because std::swap<>() is not specilized for boost::scoped_ptr<> and the generic definition of std::swap<>() requires the argument type to be copyable (and boost::scoped_ptr<> is noncopyable). I think I have read somewhere (but perhaps I'm wrong) that specialization of std::swap<>() for user defined types is allowed by the standard, so is there any other reason for not defining the global swap functions in namespace std? Michele Galante Zucchetti Centro Sistemi s.p.a. m.galante@centrosistemi.it
On Thursday 26 September 2002 10:30 am, Galante Michele wrote:
Why is the global swap() function defined in namespace boost and not as a specialization of std::swap<>() in namespace std?
Most Boost classes are templates, so we cannot define a specialization of std::swap<>() for them, and we aren't allowed to add an overload into std::.
Suppose I have a template function like the following:
#include <algorithms>
template <typename T> void do_something_and_swap(T &a, T &b) { // do something ... std::swap(a, b); }
I want this template function to work with every type that is "swappable", but if I try to use it with boost::scoped_ptr<> the compiler fails because std::swap<>() is not specilized for boost::scoped_ptr<> and the generic definition of std::swap<>() requires the argument type to be copyable (and boost::scoped_ptr<> is noncopyable).
You want: template <typename T> void do_something_and_swap(T &a, T &b) { // do something ... using std::swap; swap(a, b); } Argument-dependent lookup will ensure that any 'swap' functions in the namespaces used by 'T' will be included in the set of known swap functions, along with std::swap. Overloading and partial ordering of function templates will then take over to ensure that the appropriate swap(a, b) will be called (even if it is boost::swap). Doug
participants (2)
-
Douglas Gregor
-
Galante Michele