Изменяет ли C ++ 11 поведение явного вызова std :: swap, чтобы обеспечить обнаружение подкачки, находящейся в ADL, например boost :: swap?

Фон

Рассмотрим для этого вопроса следующий код:

#include <utility>

namespace ns
{
    struct foo
    {
        foo() : i(0) {}
        int i;

    private:
        foo(const foo&); // not defined,
        foo& operator=(const foo&); // non-copyable
    };

    void swap(foo& lhs, foo& rhs)
    {
        std::swap(lhs.i, rhs.i);
    }
}

template <typename T>
void do_swap(T& lhs, T& rhs); // implementation to be determined

int main()
{
    ns::foo a, b;
    do_swap(a, b);
}

В C ++ 03 эта реализацияdo_swap будет считаться «сломанным»:

template <typename T>
void do_swap(T& lhs, T& rhs)
{
    std::swap(lhs, rhs);
}

Явно указавstd::запрещаетns::swap от поиска через аргумент-зависимый поиск. (Затем не удается скомпилировать, потому чтоstd::swap пытается скопироватьfoo, что недопустимо.) Вместо этого мы делаем это:

template <typename T>
void do_swap(T& lhs, T& rhs)
{
    using std::swap; // allow std::swap as a backup if ADL fails to find a swap
    swap(lhs, rhs); // unqualified call to swap, allow ADL to operate
}

В настоящее времяns::swap найден иstd::swap, будучи менее специализированным, не используется. Это уродливее, но работает и понятно задним ходом.boost::swap оборачивает это хорошо для нас (и обеспечивает перегрузки массива):

#include <boost/swap.hpp>

template <typename T>
void do_swap(T& lhs, T& rhs)
{
    boost::swap(lhs, rhs); // internally does what do_swap did above
}
Вопрос

Мой вопрос, таким образом,: делаетstd::swap взять на себя поведениеboost::swap в С ++ 11? Если нет, то почему?

Мне кажется очевидным, что так и должно быть. Любой код, нарушенный этим изменением, был, во-первых, довольно хрупким (алгоритмы и контейнеры, например,std::sort а такжеstd::vectorбыли занижены; Реализациям было разрешено вызывать подкачки ADL или не определено), поэтому изменения будут к лучшему. Дополнительно,std::swap теперь определено для массивов, так что об изменениях вообще не может быть и речи.

Тем не менее, в то время как §17.6.3.2 указывает, что все вызовыswap в стандартной библиотеке должно быть сделано безstd:: квалификация (устранение проблемы с алгоритмами и контейнерами, указанными выше), не затрагиваетstd::swap сам. Он даже приводит примеры обмена значениями, которые включаютusing std::swap;, Аналогично §20.2.2 (гдеstd::swap не указано ни слова по ADL.

Наконец, GCC не включает ADL в своихstd::swap реализация (как и MSVC, но это не говорит о многом). Так что я должен быть неправstd::swap берет на себя поведениеboost::swap, но я не понимаю, почему изменение не было сделано. :(И я не одинок!

Ответы на вопрос(3)

Ваш ответ на вопрос