Подтвердить что ты не робот

Вывести тип шаблона в С++

При написании общих функций для диапазонов "итератор" я обычно делаю:

template <typename Iter> auto func(Iter &first, Iter &last)
{
    using IterType = typename std::decay<decltype(*first)>::type;
    ...
}

Другой способ:

template <typename Iter> auto func(Iter &first, Iter &last)
{
    using IterType = typename std::iterator_traits<Iter>::value_type;
    ...
}

И еще третья:

template <typename Iter> auto func(Iter &first, Iter &last)
{
    using IterType = typename Iter::value_type;
    ...
}

Без применения iterator_traits.

В теории мои функции должны принимать только итераторы как first и last, а вторая форма идеально (imho) - самый идиоматический способ получить тип. Но использует typename std::decay<decltype(*first)>::type самую общую идиому, чтобы не налагать ограничений на Iter, как имеющие value_type, определенные?

4b9b3361

Ответ 1

Второй - самый идиоматический.

  • Первый не работает с прокси (std::vector <bool> )
  • Третий не работает с указателями.

Ответ 2

Ни один из них не является вполне идиоматическим; вы должны передавать итераторы по значению, а не по ссылке. Здесь подпись для for_each в gcc 4.9:

template<typename _InputIterator, typename _Function>
_Function
for_each(_InputIterator __first, _InputIterator __last, _Function __f)

Как вы можете видеть, он прошел по значению. Ваши функции не будут работать в идиоматическом использовании:

func(v.begin(), v.end()); // error, binding non-const ref to rvalue!

Кроме того, переход через iterator_traits больше, чем просто идиоматический, это в основном требуется. Что касается STL, то такие typedef определяются только через iterator_traits: http://en.cppreference.com/w/cpp/concept/ForwardIterator. iterator_traits предоставляет разумные значения по умолчанию для общего случая, но может быть специализированным (как и для указателей) делать разные вещи. Не проходя через iterator_traits в основном означает, что кто-то может написать совместимый итератор, который работал с STL, но не с вашим кодом.