Изменяет ли 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
, но я не понимаю, почему изменение не было сделано. :(И я не одинок!