O C ++ 11 altera o comportamento de chamar explicitamente std :: swap para garantir a troca de ADLs localizadas, como boost :: swap?

Fund

Considere esta pergunta o seguinte código:

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

No C ++ 03, esta implementação dedo_swap seria considerado "quebrado":

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

Por especificar explicitamentestd::, proíbens::swap seja encontrado através da pesquisa dependente de argumento. (Falha na compilação porquestd::swap tenta copiar umfoo, o que não é permitido.) Em vez disso, fazemos o seguinte:

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
}

Agorans::swap é encontrado estd::swap, sendo menos especializado, não é usado. É mais feio, mas funciona e é compreensível em retrospectiva.boost::swap @ encerra isso muito bem para nós (e fornece sobrecargas na matriz

#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
}
Questã

Minha pergunta é assim: fazstd::swap assuma o comportamento deboost::swap em C ++ 11? Se não, por quê?

Para mim, parece óbvio que deveria. Qualquer código quebrado pela mudança provavelmente era bastante instável em primeiro lugar (algoritmos e contêineres, comostd::sort estd::vector, foram subespecificados; as implementações foram autorizadas a chamar swap de ADLs ou não indeterminadamente); portanto, a mudança seria para melhor. Além disso,std::swap agora está definido para matrizes, portanto a alteração não está fora de questã

No entanto, enquanto §17.6.3.2 especifica que todas as chamadas paraswap na biblioteca padrão deve ser feito semstd:: qualificação (corrigindo o problema com algoritmos e contêineres mencionados acima), ele não toca emstd::swap em si. Ele ainda fornece exemplos de valores de troca que incluemusing std::swap;. Da mesma forma §20.2.2 (ondestd::swap é especificado) não diz uma palavra no AD

Por fim, o GCC não habilita ADL em seusstd::swap implementação (nem o MSVC, mas isso não está dizendo muito). Então, eu devo estar errado questd::swap assume o comportamento deboost::swap, mas não entendo por que a alteração não foi feita. :(E eu não estou sozinho!

questionAnswers(6)

yourAnswerToTheQuestion