重载用户定义类型的全局交换

2022-01-07 00:00:00 swap standards c++ stl

C++ 标准禁止在名称空间 std 中声明类型或定义任何内容,但它允许您为用户定义的类型专门化标准 STL 模板.

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.

通常,当我想为我自己的自定义模板类型专门化 std::swap 时,我只是这样做:

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?

推荐答案

你所拥有的不是专业化,它是重载,正是标准所禁止的.(但是,它目前在实践中几乎总是有效,并且您可能可以接受.)

What you have is not a specialization, it is overloading and exactly what the standard prohibits. (However, it will almost always currently work in practice, and may be acceptable to you.)

以下是您为类模板提供自己的交换的方法:

Here is how you provide your own swap for your class template:

template<class T>
struct Ex {
  friend void swap(Ex& a, Ex& b) {
    using std::swap;
    swap(a.n, b.n);
  }
  T n;
}

这里是你如何调用 swap,你会注意到 Ex 的 swap 中也使用了它:

And here is how you call swap, which you'll notice is used in Ex's swap too:

void f() {
  using std::swap; // std::swap is the default or fallback
  Ex<int> a, b;
  swap(a, b); // invokes ADL
}

相关:函数模板专业化重要性和必要性

相关文章