У меня есть шаблонная функция C ++, которая принимает обобщенные итераторы c в качестве аргументов, как показано ниже:
(она обрабатывает все элементы от first
до, но исключая last
)
void update(const std::uint8_t *const data, const size_t len)
{
/* ... */
}
template<typename iterator_type>
void update(const iterator_type &first, const iterator_type &last)
{
typedef typename std::iterator_traits<iterator_type>::value_type value_type;
for (iterator_type iter = first; iter != last; ++iter)
{
update(reinterpret_cast<const std::uint8_t*>(std::addressof(*iter)), sizeof(value_type));
}
}
Пока это работает. Моя единственная проблема: если value_type итератора является типом указателя, то эта функция обрабатывает значение указателя (адрес памяти), а не фактическое значение (объект), на которое указывает указатель. Итак, я хотел бы обрабатывать типы указателей специально. Есть ли хороший способ в C ++ обеспечить специализацию этой функции шаблона для итераторов, чей value_type является типом указателя?
Я пытался решить эту проблему с помощью одной функции и if(is_pointer)... else...
построить, как это:
void update(const iterator_type &first, const iterator_type &last)
{
typedef typename std::iterator_traits<iterator_type>::value_type value_type;
if(std::is_pointer<value_type>::value)
{
for (iterator_type iter = first; iter != last; ++iter)
{
update(reinterpret_cast<const std::uint8_t*>(*iter), sizeof(std::pointer_traits<value_type>::element_type));
}
}
else
{
for (iterator_type iter = first; iter != last; ++iter)
{
update(reinterpret_cast<const std::uint8_t*>(std::addressof(*iter)), sizeof(value_type));
}
}
}
... но, к сожалению, это не компилируется для типов без указателей:
error C2039: 'element_type': is not a member of 'std::pointer_traits<value_type>'