When writing generic functions for "iterator" ranges I usually do:
template <typename Iter> auto func(Iter &first, Iter &last)
{
using IterType = typename std::decay<decltype(*first)>::type;
...
}
Another way seems to be:
template <typename Iter> auto func(Iter &first, Iter &last)
{
using IterType = typename std::iterator_traits<Iter>::value_type;
...
}
And yet a third:
template <typename Iter> auto func(Iter &first, Iter &last)
{
using IterType = typename Iter::value_type;
...
}
Without applying iterator_traits
.
In theory, my functions should only receive iterators as first
and last
and the second form would ideally (imho) the most idiomatic way to get the type. But is using typename std::decay<decltype(*first)>::type
the most generic idiom in order to not impose restrictions to Iter
like having a value_type
defined?