在What is the copy-and-swap idiom中,此示例显示:
friend void swap(dumb_array& first, dumb_array& second) // nothrow
{
// enable ADL (not necessary in our case, but good practice)
using std::swap;
// by swapping the members of two classes,
// the two classes are effectively swapped
swap(first.mSize, second.mSize);
swap(first.mArray, second.mArray);
}
using std::swap
究竟是如何启用ADL的?ADL只需要一个不限定的名称。对于using std::swap
,我看到的唯一好处是,由于std::swap
是一个函数模板,所以您可以在调用(swap<int, int>(..)
)中使用模板参数列表。
如果不是这样的话,那么using std::swap
是干什么的呢?
发布于 2015-01-24 21:56:24
“启用ADL”注释适用于
std::swap(first.mSize, second.mSize);
std::swap(first.mArray, second.mArray);
至
using std::swap;
swap(first.mSize, second.mSize);
swap(first.mArray, second.mArray);
您说得对,ADL只需要一个不限定的名称,但这就是如何重新处理代码来使用不限定的名称。
只是平淡
swap(first.mSize, second.mSize);
swap(first.mArray, second.mArray);
无法工作,因为对于许多类型,ADL不会找到std::swap
,而且在范围内也没有其他可用的swap
实现。
发布于 2015-04-17 17:48:00
只是想补充一下为什么这个成语会被使用,这似乎是最初问题的精神所在。
这个成语在许多实现交换的std库类中使用。来自http://www.cplusplus.com/reference/algorithm/swap/
标准库的许多组件(在std中)以不限定的方式调用交换,以允许调用非基本类型的自定义重载,而不是这个通用版本:在与提供它们的类型相同的名称空间中声明的自定义重载通过对此泛型版本的依赖于参数的查找来选择。
因此,使用非限定的“交换”来交换您所描述的函数中的成员变量的目的是为了使ADL能够为这些类找到自定义的交换函数(如果它们存在于其他地方)。
由于您所引用的类中不存在这些自定义类(在原始示例中,mSize和mArray分别是一个std::size_t和int* ),并且std::swap工作得很好,所以作者添加了一条注释,在本例中这不是必要的,而是良好的实践。如果他显式地调用std::swap,就会得到同样的结果,正如前面的答案所指出的那样。
为什么是很好的练习?因为如果您有定义自定义交换的类的成员实例,您希望行为是这样的:检查是否存在自定义交换function...if,如果它不存在,则使用它,使用std库函数。在没有自定义交换函数可用的情况下,您希望它默认为上面的链接中描述的简单的std::swap实现。因此出现了“使用”,将内置类型的交换带到命名空间中。但这会是最后一次。
另见:https://stackoverflow.com/a/2684544/2012659
如果出于某种原因,您不喜欢“使用std:: swap ",我想理论上可以通过显式调用std::swap来手动解决这个问题,使用std::swap对您所知道的每个定义的自定义交换(仍然使用ADL)进行交换。但这很容易出错..。如果没有编写这些类,您可能不知道是否存在自定义的交换。并且在std::交换和交换之间切换会导致代码混淆。最好让编译器来处理所有这些。
https://stackoverflow.com/questions/28130671
复制相似问题