Недавно я столкнулся с неким шаблоном отправки, основанным на «концепциях» типов данных (я думаю, что это правильное использование термина «концепции», если нет, атрибутов ??).
Кажется,для меня, чтобы быть немного более вовлеченным, чем то, что я видел раньше, и, по крайней мере, до оптимизации, вводит временные переменные и вызовы функций.Мой вопрос (1) все это на самом деле оптимизируется?(2) является ли это «лучшим» способом выполнения такого рода диспетчеризации на основе типов ??
Код, который я читал, имел дело с типами итераторов, поэтому я буду придерживаться этого в качестве примера шаблона.Функция iter_kind
ниже принимает переменную любого типа и возвращает фиктивную переменную определенного «концептуального» типа.Что-то вроде random_access_iterator_kind
, или если _Iter
был не-итерационным типом null_iterator_kind
.
template <typename _Iter>
INLINE_CALL typename iterator_traits<_Iter>::iter_kind iter_kind(_Iter&)
{
typename iterator_traits<_Iter>::iter_kind _ret;
return ( _ret );
}
. Он работает с использованием обычной метамагии через специализацию класса iterator_traits
.Я доволен всем этим.
iter_kind
привыкает делегировать различные реализации конкретной функции, например:
template <typename _Iter, typename _Pred>
_Iter binary_search(_Iter head, _Iter tail, _Pred pred_less)
{
binary_search_impl(head, tail, pred_less, iter_kind(head));
}
template <typename _Iter, typename _Pred>
_Iter binary_search_impl(_Iter head, _Iter tail, _Pred pred_less,
random_access_iterator_kind)
{ // actual implementation...
}
template <typename _Iter, typename _Pred>
_Iter binary_search_impl(_Iter head, _Iter tail, _Pred pred_less,
bidirectional_iterator_kind)
{
assert(false); // can't do bin search without random access iters!!
}