unsigned char makes this complicated. If you know that your system uses 2s, add 1 byte 8 bits of unsigned char and char , and the implicit conversion from unsigned char to char does what you want (this is not always the case!), And your null array buffer is complete (t .e. characters after the first 0 should be canceled), this function works:
template<std::size_t N> std::string to_string( std::array<unsigned char, N> const& arr ) { std::string retval; for( auto c : arr ) { if (!c) return retval; retval.push_back(c); } return retval; }
I have included some paranoia about the possibility that the array may be "complete" and not have a null terminator.
If you really want all 16 unsigned char , even if some of them are null, you want to use this:
std::string str( arr.begin(), arr.end() );
which should use an implicit conversion from unsigned char to char .
If implicit casting does not do what you want, and you know that the memory array is actually a char array, although its type is unsigned char , you need to do some reinterpretation.
For the case with zero completion:
template<std::size_t N> std::string to_string_helper( const char* buf ) { std::string retval; if (!buf) return retval; for ( const char* it = buf; it < (buf+N); ++it ) { if (!*it) return retval; retval.push_back(*it); } return retval; } template<std::size_t N> std::string to_string_2( std::array<unsigned char, N> const& arr ) { return to_string_helper<N>( arr.data() ); }
and for the case of "whole buffer":
template<std::size_t N> std::string to_string_2( std::array<unsigned char, N> const& arr ) { const char* str = reinterpret_cast<const char*>(arr.data()); return std::string( str, str+N ); }