Вопрос по бусту:: своп

Пара вопросов по boost::swap, Пожалуйста, обратитесь к приведенному ниже коду, который является в основном вырезкой из boost/swap.hpp, Я имею в виду библиотеку версии 1.43.0.

namespace boost_swap_impl
    {
      template<class T>
      void swap_impl(T& left, T& right)
      {
        using namespace std;//use std::swap if argument dependent lookup fails
        swap(left,right);
      }

  template<class T, std::size_t N>
  void swap_impl(T (& left)[N], T (& right)[N])
  {
    for (std::size_t i = 0; i < N; ++i)
    {
      ::boost_swap_impl::swap_impl(left[i], right[i]);
    }
  }
}

namespace boost
{
  template<class T1, class T2>
  void swap(T1& left, T2& right)
  {
    ::boost_swap_impl::swap_impl(left, right);
  }
}
  1. Почему boost::swap объявлен как template <typename T1, typename T2> когда в остальной части кода все имеет дело с одним и тем же типом?
  2. Если я определю свою собственную глобальную функцию void swap(T&, T&) Я вижу, что это глобальная функция, которая вызывается из swap_impl(T& left, T& right), Разве это не конфликт и, следовательно, условие ошибки, так как swap_impl также использует namespace std который определил своп?

1 ответ

Решение
  1. Это делает его менее специализированным, чем std::swap так что вы не получите ошибки неоднозначности перегрузки, когда оба std::swap а также boost::swap находятся в области (std::swap будет иметь приоритет).
  2. Нет, не-шаблоны всегда имеют приоритет над шаблонами при разрешении перегрузки, поэтому не шаблон в области имен swap будет иметь приоритет над обоими boost::swap а также std::swap (как и шаблон в пространстве имен swap перегружен для UDT - думаю, частично-специализированный, но не совсем..). Обратите внимание, что в отличие от std::swap, boost::swap написано явно, чтобы воспользоваться ADL.

Вот что говорит C++03 в отношении обоих пунктов - [over.match.best] (§13.3.3/1):

Определить ICSя(F) следующее:

  • если F статическая функция-член ICS1(F) определяется так, что ICS1(F) не лучше и не хуже, чем ICS1(G) для любой функции Gи, симметрично, ICS1(G) не лучше и не хуже, чем ICS1(F); иначе,
  • пусть ICSя(F) обозначает последовательность неявного преобразования, которая преобразует i-й аргумент в списке в тип i-го параметра жизнеспособной функции F, 13.3.3.1 определяет последовательности неявного преобразования, а 13.3.3.2 определяет, что означает, что одна последовательность неявного преобразования является лучшей последовательностью преобразования или худшей последовательностью преобразования, чем другая.

Учитывая эти определения, жизнеспособная функция F1 определяется как лучшая функция, чем другая жизнеспособная функция F2 если для всех аргументов i, ICSi(F1) не хуже последовательности преобразования, чем ICSi(F2), а потом

  • для некоторого аргумента j, ICSj(F1) является лучшей последовательностью преобразования, чем ICSj(F2) или, если не так,
  • F1 это не шаблонная функция и F2 это специализация шаблона функции, или, если не так,
  • F1 а также F2 являются специализациями шаблонов функций, а шаблон функций для F1 более специализирован, чем шаблон для F2 в соответствии с правилами частичного заказа, описанными в 14.5.5.2, или, если нет,
  • контекст представляет собой инициализацию с помощью пользовательского преобразования (см. 8.5, 13.3.1.5 и 13.3.1.6) и стандартной последовательности преобразования из возвращаемого типа F1 для типа назначения (т. е. тип инициализируемого объекта) является лучшей последовательностью преобразования, чем стандартная последовательность преобразования из возвращаемого типа F2 к типу назначения.
Другие вопросы по тегам