例如,我有一个管理POSIX fd的类:

class remote_connection:
{
public:
  explicit remote_connection( int socket_fd ) : socket_fd(socket_fd) {}
  ~remote_connection() { close( socket_fd); }

  /* no copy semantic */
  remote_connection( const remote_connection& other ) = delete;
  remote_connection& operator=( const remote_connection& rhs ) = delete;

  remote_connection( remote_connection&& other )
  {
    socket_fd = other.socket_fd;
    other.socket_fd = -1;
  }

  remote_connection& operator=( remote_connection&& rhs )
  {
    close( socket_fd );
    socket_fd = rhs.socket_fd;

    rhs.socket_fd = -1;

    return *this;
  }

private:
  int socket_fd;
};

在代码中:
/* let '42' and '24' be a valid fds */
remote_connection cl_1( 42 ), cl_2( 24 );

...

using std::swap;

swap( cl_1, cl_2 );

对于remote_connection的这种实现,ADL找不到用户定义的swap并回退到没有remote_connection专门化的std namespace ,因此编译器从std::swap<remote_connection>()模板函数实例化了std::swap<T>()函数。该函数实现调用move ctor和move赋值运算符,后者导致对象交换其内容。

我可以为swap()实现一个remote_connection,这将导致SAME结果。

所以问题是,对于swap无法做到的类,我该怎么做呢?还是为什么如果编译器可以实例化类型,甚至对于管理不重要的子对象(PO​​SIX fd,指针等)的类型,为什么还要为该类型提供实现呢?

最佳答案

全局std::swap需要创建一个临时文件。基于自定义类的交换将了解该类的内部,并且可以更有效地执行交换,而不必创建该类类型的另一个变量。

在您的情况下,内部交换可以交换内部socket_id值,而不必在move构造函数和move赋值运算符(将被调用两次)中做所有额外的工作。

关于c++ - 为用户定义的类型提供swap()的原因是什么?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/49959722/

10-13 05:55