C++ 成员职能互换背后的基本原理

C++ 成员职能互换背后的基本原理,c++,language-lawyer,swap,generic-programming,C++,Language Lawyer,Swap,Generic Programming,在标准库中,如果类类型有专门的交换算法,那么它将有一个成员函数swap和一个自由函数swap,该函数只转发给成员函数。我不太明白这两种方法(以及代码复制)背后的原理,但不仅仅是免费函数。请注意,当我说自由函数时,我的意思是专门的自由交换函数,而不是通用的std::swap函数模板。这样一个专用函数可能通过成为相关类的朋友而具有访问相关类的特权 我有两点要支持,只保留free函数而不是member函数。首先,它形成了一个更通用的交换接口,以便于编写通用算法,因为像数组这样的非类类型不能有成员函数。

在标准库中,如果类类型有专门的交换算法,那么它将有一个成员函数
swap
和一个自由函数
swap
,该函数只转发给成员函数。我不太明白这两种方法(以及代码复制)背后的原理,但不仅仅是免费函数。请注意,当我说自由函数时,我的意思是专门的自由交换函数,而不是通用的
std::swap
函数模板。这样一个专用函数可能通过成为相关类的朋友而具有访问相关类的特权


我有两点要支持,只保留free函数而不是member函数。首先,它形成了一个更通用的交换接口,以便于编写通用算法,因为像数组这样的非类类型不能有成员函数。第二,swap是一种包含两个操作数的二进制操作,它具有对称性。使用任意一个操作数都没有偏差的自由函数执行交换更自然、更直观。因此,当使用成员函数
swap
时,我总是觉得有点奇怪,好像我在执行基于调用对象的操作。

自由函数看不到类的私有部分,因此实际功能需要作为类成员提供。但是,您想要自由函数,因为它是一个定制点(使用ADL);因此,一个通用算法将调用free
swap
,以实现适合当前类型的任何交换

成员函数对于诸如
T().swap(existing_thing)
之类的构造也很有用,因为自由函数需要左值参数


我想另一种选择是使
交换
成为类内声明的公共好友函数,这也可以通过ADL找到。

自由函数无法看到类的私有部分,因此实际功能需要作为类成员提供。但是,您想要自由函数,因为它是一个定制点(使用ADL);因此,一个通用算法将调用free
swap
,以实现适合当前类型的任何交换

成员函数对于诸如
T().swap(existing_thing)
之类的构造也很有用,因为自由函数需要左值参数


我想另一种选择是使
交换
成为类内声明的公共好友函数,这也可以通过ADL找到。

自由函数无法看到类的私有部分,因此实际功能需要作为类成员提供。但是,您想要自由函数,因为它是一个定制点(使用ADL);因此,一个通用算法将调用free
swap
,以实现适合当前类型的任何交换

成员函数对于诸如
T().swap(existing_thing)
之类的构造也很有用,因为自由函数需要左值参数


我想另一种选择是使
交换
成为类内声明的公共好友函数,这也可以通过ADL找到。

自由函数无法看到类的私有部分,因此实际功能需要作为类成员提供。但是,您想要自由函数,因为它是一个定制点(使用ADL);因此,一个通用算法将调用free
swap
,以实现适合当前类型的任何交换

成员函数对于诸如
T().swap(existing_thing)
之类的构造也很有用,因为自由函数需要左值参数


我想另一种选择是在类内声明
swap
一个公共友元函数,也可以通过ADL找到。

专用的免费swap函数可以通过声明类为友元来访问该类。此外,我不认为像
t().swap(existing\u thing)
这样的构造有什么用处,因为你可以简单且更容易地清除
existing\u thing
@Lingxi:Clearing保留分配;用空的东西交换不需要。如果要支持这种用法,只需将专用的自由函数设计为采用通用引用类型。专用的自由交换函数可以通过将类声明为友元来对该类进行特权访问。此外,我不认为像
t().swap(existing\u thing)
这样的构造有什么用处,因为你可以简单且更容易地清除
existing\u thing
@Lingxi:Clearing保留分配;用空的东西交换不需要。如果要支持这种用法,只需将专用的自由函数设计为采用通用引用类型。专用的自由交换函数可以通过将类声明为友元来对该类进行特权访问。此外,我不认为像
t().swap(existing\u thing)
这样的构造有什么用处,因为你可以简单且更容易地清除
existing\u thing
@Lingxi:Clearing保留分配;用空的东西交换不需要。如果要支持这种用法,只需将专用的自由函数设计为采用通用引用类型。专用的自由交换函数可以通过将类声明为友元来对该类进行特权访问。此外,我不认为像
t().swap(existing\u thing)
这样的构造有什么用处,因为你可以简单且更容易地清除
existing\u thing
@Lingxi:Clearing保留分配;如果要支持这种用法,可以设计专门的免费函数,使其采用通用引用类型。