什么`在类方法实现的主体内使用std :: swap`意味着什么?

Ste*_*and 26 c++ stl using std argument-dependent-lookup

在一些c ++实践中,我试图学习并采用复制交换习语,对这个问题进行彻底的解释:复制交换习语.

但我发现了一些我从未见过的代码:using std::swap; // allow ADL在这个例子中

class dumb_array
{
public:
    // ...

    void swap(dumb_array& pOther) // nothrow
    {
        using std::swap; // allow ADL    /* <===== THE LINE I DONT UNDERSTAND */

        swap(mSize, pOther.mSize); // with the internal members swapped,
        swap(mArray, pOther.mArray); // *this and pOther are effectively swapped
    }
};
Run Code Online (Sandbox Code Playgroud)
  1. using std::swap;在函数实现的主体内部意味着什么?
  2. ADL是什么意思?

MSa*_*ers 61

这种机制通常用于模板化代码,即template <typename Value> class Foo.

现在的问题是使用哪个交换.std::swap<Value>会有用,但可能不太理想.有一个很好的机会,swap类型的更好的重载Value,但在哪个命名空间?它几乎肯定不在std::(因为那是非法的),但很可能在命名空间中Value.可能,但远非确定.

在这种情况下,swap(myValue, anotherValue)将为您提供"最佳"交换.Argument Dependent Lookup将在命名空间中找到任何交换Value.否则该using指令将启动,std::swap<Value>并将被实例化和使用.

在您的代码中,mSize可能是一个整数类型和mArray一个指针.它们都没有关联的命名空间,并且std::swap无论如何都具有99.9%的确定性.因此,using std::swap;这里的声明似乎毫无用处.

  • @dribeas:确实专门化`std :: swap`是合法的,如果对你的用户有疑问,你应该专门研究`std :: swap`*和*在你自己的命名空间中提供一个`swap`,由ADL找到.但是专门化`std :: swap`是有限制的,其中一个杀手就是你不能*部分*专门化它,因为它是一个函数模板,所以如果你编写了一个类模板(比如一个新的容器) ,你不能为它专门化`std :: swap`,因此你必须采用ADL路线.但是,MSalters在他所说的内容中是正确的:你不能超载`std :: swap`,只能专门化. (9认同)
  • 我相信在`std`命名空间内提供标准模板化函数的特化是非常合法的.§17.4.3.1/ 1"程序可以将任何标准库模板的模板特化添加到命名空间std.标准库模板的这种特化(完整或部分)会导致未定义的行为,除非声明取决于用户定义的名称外部链接,除非专门化符合原始模板的标准库要求"也就是说,在`std`命名空间中实现`swap`特化是不常见的. (6认同)

Ben*_*oit 11

using关键字已范围的影响.

这意味着std::swap可以swapusing关键字的范围内引用它.

  • 我认为ADL在这种情况下只是意味着"依赖于参数的查找".这允许代码在定义或不定义本地交换函数的情况下使用"交换".如果本地不存在,则使用std :: swap (19认同)
  • 说实话,这是一个无用的答案.它没有解释`using std :: swap`和ADL的交互.MSalters的答案应该是被接受的答案. (5认同)
  • @vmpstr:如果你把它作为一个单独的答案,你只要因为我投票而获得10点声望. (3认同)