简体   繁体   English

“使用std :: swap”如何启用ADL?

[英]How does “using std::swap” enable ADL?

In What is the copy-and-swap idiom this example is shown: 什么是复制和交换习语这个例子显示:

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);
}

How exactly does using std::swap enable ADL? using std::swap启用ADL到底是怎么回事? ADL only requires an unqualified name. ADL只需要一个不合格的名称。 The only benefits I see for using std::swap is that since std::swap is a function template you can use a template argument list in the call ( swap<int, int>(..) ). 我看到using std::swap的唯一好处是,因为std::swap是一个函数模板,所以你可以在调用中使用模板参数列表( swap<int, int>(..) )。

If that is not the case then what is using std::swap for? 如果不是这样的话那么using std::swap是什么?

Just wanted to add why this idiom is used at all, which seemed like the spirit of the original question. 只想添加为什么这个成语被使用,这似乎是原始问题的精神。

This idiom is used within many std library classes where swap is implemented. 这个习惯用法在许多实现交换的std库类中使用。 From http://www.cplusplus.com/reference/algorithm/swap/ : 来自http://www.cplusplus.com/reference/algorithm/swap/

Many components of the standard library (within std) call swap in an unqualified manner to allow custom overloads for non-fundamental types to be called instead of this generic version: Custom overloads of swap declared in the same namespace as the type for which they are provided get selected through argument-dependent lookup over this generic version. 标准库的许多组件(在std中)以不合格的方式调用swap,以允许调用非基本类型的自定义重载而不是此通用版本:交换的自定义重载在与它们所属的类型相同的命名空间中声明提供通过依赖于参数的查找来选择此通用版本。

So the purpose of using an unqualified "swap" to swap member variables in the function you described is so that ADL can find customized swap functions for those classes (if they exist elsewhere). 因此,使用非限定“交换”来交换您所描述的函数中的成员变量的目的是使ADL可以为这些类找到自定义交换函数(如果它们存在于其他地方)。

Since these customized classes don't exist within the class you're referencing (mSize and mArray is a std::size_t and an int*, respectively, in the original example), and the std::swap works just fine, the author added a comment that this was not necessary in this case, but good practice. 由于这些自定义类在您引用的类中不存在(mSize和mArray在原始示例中分别是std :: size_t和int *),并且std :: swap工作得很好,作者他补充说,在这种情况下这不是必需的,但是做法很好。 He would have gotten the same results had he explicitly called std::swap, as is pointed out in the previous answer. 如果他明确地调用了std :: swap,他会得到相同的结果,如前面的答案中所指出的那样。

Why is it good practice? 为什么这是好的做法? Because if you have as members instances of classes for which custom swap is defined, you want the behavior to be this: check for a customized swap function...if it exists, use it, if it does not exist, use the std library functions. 因为如果你有定义自定义交换的类的成员实例,你希望行为是这样的:检查自定义交换函数...如果它存在,使用它,如果它不存在,使用std库职能。 In the cases where there are no customized swap functions available, you want it to default to the simple std::swap implementation described in the link above. 在没有可用的自定义交换函数的情况下,您希望它默认为上面链接中描述的简单std :: swap实现。 Hence the "using", to bring swap for built-in types into the namespace. 因此,“使用”将内置类型的交换带入命名空间。 But those will be tried last. 但最后会尝试这些。

See also: https://stackoverflow.com/a/2684544/2012659 另请参见: https//stackoverflow.com/a/2684544/2012659

If for some reason you hate the "using std::swap", I suppose you could in theory resolve this manually by explicitly calling std::swap for everything you'd want to swap using std::swap and using the unqualified swap for every custom swap you know is defined (still found using ADL). 如果由于某种原因你讨厌“使用std :: swap”,我想你理论上可以通过显式调用std :: swap为你想要使用std :: swap交换的所有内容并使用不合格的交换来解决这个问题。您知道的每个自定义交换都已定义(仍然使用ADL找到)。 But this is error prone ... if you didn't author those classes you may not know if a customized swap exists for it. 但这很容易出错...如果您没有创作这些类,您可能不知道是否存在自定义交换。 And switching between std::swap and swap makes for confusing code. 并且在std :: swap和swap之间切换会使代码混乱。 Better to let the compiler handle all of this. 最好让编译器处理所有这些。

The "enable ADL" comment applies to the transformation of “启用ADL”注释适用于转换

std::swap(first.mSize, second.mSize);
std::swap(first.mArray, second.mArray);

to

using std::swap;
swap(first.mSize, second.mSize);
swap(first.mArray, second.mArray);

You're right, ADL only requires an unqualified name, but this is how the code is re-worked to use an unqualified name. 你是对的,ADL只需要一个不合格的名称,但这就是代码重新使用非限定名称的方式。

Just plain 简单明了

swap(first.mSize, second.mSize);
swap(first.mArray, second.mArray);

wouldn't work, because for many types, ADL won't find std::swap , and no other usable swap implementation is in scope. 不起作用,因为对于许多类型,ADL将找不到std::swap ,并且范围内没有其他可用的swap实现。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM