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