CRC function duplication – differ only in pointer vs iterator signature

This is a CRC function generated by pyCRC and changed by me:

static inline crc_t crc_update(crc_t          crc,
char const *   data,
long long      data_len)
{
while (data_len--)
{
crc = (crc_table[(crc ^ *data) & 0xff] ^ (crc >> 8));
++data;
}
return crc;
}


I made an iterator version of it:

static inline crc_t crc_update(crc_t                          crc,
std::istreambuf_iterator<char> data,
long long                      data_len)
{
/* body identical to the above */
}


Is there a way I can avoid duplication? (The main purpose of the code is to be fast.)

The obvious way is to replace the type that changes with a templated type, like this:

template<typename T>
static inline crc_t crc_update(crc_t          crc,
T              data,
long long      data_len)
{
while (data_len--)
{
crc = (crc_table[(crc ^ *data) & 0xff] ^ (crc >> 8));
++data;
}
return crc;
}


Or in words: put template<typename T> in front of the function, and replace all char const * with T.

There are some details about inserting typename in some cases to help the compiler, but those do not apply in this case.

To prevent incorrect usage, one might add some checks to ensure that only 8 bit types can be used. However, that is advanced stuff and not required to answer your question.