Overloading global swap for user-defined type

2019-01-17 17:28发布

The C++ standard prohibits declaring types or defining anything in namespace std, but it does allow you to specialize standard STL templates for user-defined types.

Usually, when I want to specialize std::swap for my own custom templated type, I just do:

namespace std
{
  template <class T>
  void swap(MyType<T>& t1, MyType<T>& t2)
  {
     t1.swap(t2);
  }
}

...and that works out fine. But I'm not entirely sure if my usual practice is standard compliant. Am I doing this correctly?

7条回答
贼婆χ
2楼-- · 2019-01-17 17:57

What you're doing is an overload and not a template specialization. The standard does not allow you to overload inside namespace std (17.6.4.2.1 §1)

The behavior of a C++ program is undefined if it adds declarations or definitions to namespace std or to a namespace within namespace std unless otherwise specified. A program may add a template specialization for any standard library template to namespace std only if the declaration depends on a user-defined type and the specialization meets the standard library requirements for the original template and is not explicitly prohibited.

Therefore, prefer to put your template type into your own namespace and define a non-member swap() within that namespace (this is not strictly necessary, but good practice). This way swap(x,y) will work from anywhere via argument dependent lookup (ADL, aka Koenig lookup), if x or y are in your namespace.

namespace my_ns {

template <typename T> class MyType
{
public:
    void swap( MyType & other ) noexcept;
};

template <typename T>
void swap( MyType<T> & lhs, MyType<T> & rhs ) noexcept
{
    lhs.swap(rhs);
}

} // namespace my_ns

Code using swap() should normally use the using namespace std technique. This way your version of swap will be found by ADL and it will be prefered to the std::swap() function, since it is more specialized.

// client code
MyType<Bla> x, y;
/* ... some code ... */
using namespace std;
swap( x, y ); // will call your swap version
查看更多
登录 后发表回答