Почему Boost.Range range_begin / end free перегружены как для константных, так и для неконстантных ссылок?

Я нашел этот интересный бит в Boost.Range:

При предоставлении отдельно стоящие функции range_begin/end(), документы утверждают, что:

range_begin() а также range_end() должен быть перегружен для обоих const
а также mutable ссылочные аргументы.

И действительно, глядя на их значения по умолчанию в end.hpp, мы видим:

    //////////////////////////////////////////////////////////////////////
// pair
//////////////////////////////////////////////////////////////////////

template< typename Iterator >
inline Iterator range_end( const std::pair<Iterator,Iterator>& p )
{
return p.second;
}

template< typename Iterator >
inline Iterator range_end( std::pair<Iterator,Iterator>& p )
{
return p.second;
}

Вы заметите (и пример приведен в документах также делает это), что обе версии возвращают одинаковые Iterator тип.

Зачем нам обе эти перегрузки в первую очередь? Это сделать ADL Работа?

1

Решение

Вам, очевидно, нужно const & версия, потому что в противном случае ваш range_begin было бы невозможно вызвать для объектов с постоянным соответствием.

Менее очевидно, почему вы также нуждаетесь в & версия, но она проста: если вы ее не предоставите, ваша пользовательская функция будет хуже, чем собственная версия Boost.

Вот краткий пример без Boost:

namespace M {
struct S { };
void f(const S &);
}

namespace N {
template <typename T>
void f(T &);

template <typename T>
void g(T &t) { f(t); }
}

void h() {
M::S s {};
N::g(s);
}

Здесь, во время создания N::g<M::S>безоговорочный вызов f(t) сделан, и аргумент t имеет тип M::S, Есть два кандидата: N::f<M::S> находится в том же пространстве имен, но ADL также находит M::f, Первый параметр M::S &, Последний является const M::S &, Это означает, что первое лучше подходит, даже если вы действительно хотите версию в пространстве имен M использоваться.

Дополнительная перегрузка M::f(S &) избегает этой проблемы.

3

Другие решения

Других решений пока нет …

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector