unsigned char
делает это сложно. Если вы знаете, что ваша система использует 2s дополнение 1 байт 8 бит unsigned char
и char
, а неявное преобразование с unsigned char
в char
делает то, что вы хотите (это не всегда так!), И ваш буфер массива имеет нулевое завершение (т.е. символы после первый 0
один должны быть отброшено), эта функция работает:
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;
}
Я включил некоторую паранойю о возможности того, что массив может быть «полным» и отсутствовать нулевой терминатор.
Если вы на самом деле хотите все 16 unsigned char
, даже если некоторые из них нулю, вы будете хотеть использовать это:
std::string str(arr.begin(), arr.end());
, который следует использовать неявное преобразование из unsigned char
в char
.
Если неявное приведение не делает то, что вы хотите, и вы знаете, что память array
«s фактически массив char
, даже если его тип unsigned char
, что вам нужно сделать некоторые переинтерпретировать литье.
Для нуля случая:
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());
}
и для «всего буфера» случая:
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);
}
+1 за второй вариант, но первый не будет, если компилировать 'sss' - массив' unsigned char'. –
@AndyProwl Пропустил этот 'unsigned'. Уточнено. Я думаю, что я получил неопределенные биты поведения правильно, но не уверен. – Yakk
@AndyProwl - также не будет компилироваться, если 'sss' является массивом' signed char'. Работает только 'char'. –