Ответ 1
Он по дизайну стандарт С++ говорит, что char
, signed char
и unsigned char
- разные типы. Я думаю, вы можете использовать статическую трансляцию для преобразования.
Рассмотрим следующий код:
#include <iostream>
#include <type_traits>
int main(int argc, char* argv[])
{
std::cout<<"std::is_same<int, int>::value = "<<std::is_same<int, int>::value<<std::endl;
std::cout<<"std::is_same<int, signed int>::value = "<<std::is_same<int, signed int>::value<<std::endl;
std::cout<<"std::is_same<int, unsigned int>::value = "<<std::is_same<int, unsigned int>::value<<std::endl;
std::cout<<"std::is_same<signed int, int>::value = "<<std::is_same<signed int, int>::value<<std::endl;
std::cout<<"std::is_same<signed int, signed int>::value = "<<std::is_same<signed int, signed int>::value<<std::endl;
std::cout<<"std::is_same<signed int, unsigned int>::value = "<<std::is_same<signed int, unsigned int>::value<<std::endl;
std::cout<<"std::is_same<unsigned int, int>::value = "<<std::is_same<unsigned int, int>::value<<std::endl;
std::cout<<"std::is_same<unsigned int, signed int>::value = "<<std::is_same<unsigned int, signed int>::value<<std::endl;
std::cout<<"std::is_same<unsigned int, unsigned int>::value = "<<std::is_same<unsigned int, unsigned int>::value<<std::endl;
std::cout<<"----"<<std::endl;
std::cout<<"std::is_same<char, char>::value = "<<std::is_same<char, char>::value<<std::endl;
std::cout<<"std::is_same<char, signed char>::value = "<<std::is_same<char, signed char>::value<<std::endl;
std::cout<<"std::is_same<char, unsigned char>::value = "<<std::is_same<char, unsigned char>::value<<std::endl;
std::cout<<"std::is_same<signed char, char>::value = "<<std::is_same<signed char, char>::value<<std::endl;
std::cout<<"std::is_same<signed char, signed char>::value = "<<std::is_same<signed char, signed char>::value<<std::endl;
std::cout<<"std::is_same<signed char, unsigned char>::value = "<<std::is_same<signed char, unsigned char>::value<<std::endl;
std::cout<<"std::is_same<unsigned char, char>::value = "<<std::is_same<unsigned char, char>::value<<std::endl;
std::cout<<"std::is_same<unsigned char, signed char>::value = "<<std::is_same<unsigned char, signed char>::value<<std::endl;
std::cout<<"std::is_same<unsigned char, unsigned char>::value = "<<std::is_same<unsigned char, unsigned char>::value<<std::endl;
return 0;
}
Результат:
std::is_same<int, int>::value = 1
std::is_same<int, signed int>::value = 1
std::is_same<int, unsigned int>::value = 0
std::is_same<signed int, int>::value = 1
std::is_same<signed int, signed int>::value = 1
std::is_same<signed int, unsigned int>::value = 0
std::is_same<unsigned int, int>::value = 0
std::is_same<unsigned int, signed int>::value = 0
std::is_same<unsigned int, unsigned int>::value = 1
----
std::is_same<char, char>::value = 1
std::is_same<char, signed char>::value = 0
std::is_same<char, unsigned char>::value = 0
std::is_same<signed char, char>::value = 0
std::is_same<signed char, signed char>::value = 1
std::is_same<signed char, unsigned char>::value = 0
std::is_same<unsigned char, char>::value = 0
std::is_same<unsigned char, signed char>::value = 0
std::is_same<unsigned char, unsigned char>::value = 1
Это означает, что int
и signed int
рассматриваются как один и тот же тип, но не char
и signed char
. Почему это?
И если я могу преобразовать char
в signed char
с помощью make_signed
, как сделать обратное (преобразовать a signed char
в char
)?
Он по дизайну стандарт С++ говорит, что char
, signed char
и unsigned char
- разные типы. Я думаю, вы можете использовать статическую трансляцию для преобразования.
Существуют три различных основных типа символов: char, подписанный char и unsigned char. Хотя существует три типа символов, существует только два представления: signed и unsigned. (Plain) char использует одно из этих представлений. Какое из двух других представлений символов эквивалентно char зависит от компилятора.
В неподписанном типе все биты представляют значение. Например, 8-разрядный без знака char может содержать значения от 0 до 255 включительно.
Стандарт не определяет, как представлены типы подписей, но указывает, что диапазон должен быть равномерно распределен между положительными и отрицательными значениями. Следовательно, 8-разрядная подписанная char гарантированно сможет хранить значения от -127 до 127.
Итак, как решить, какой тип использовать?
Вычисления с использованием char обычно проблематичны. char по умолчанию подписан на некоторых машинах и без знака на других. Поэтому мы не должны использовать (plain) char в арифметических выражениях. Используйте его только для хранения символов. Если вам нужно маленькое целое число, явно укажите либо подписанный char, либо без знака char.
Действительно, стандарт точно говорит, что char, подписанный char и unsigned char - 3 разных типа. A char обычно составляет 8 бит, но этот стандарт не накладывается. 8-разрядное число может кодировать 256 уникальных значений; разница заключается только в том, как интерпретируются эти 256 уникальных значений. Если вы считаете 8-битное значение в качестве знакового двоичного значения, оно может представлять целочисленные значения от -128 (все 1) до +127. Если вы считаете его неподписанным, он может представлять значения от 0 до 255. По стандарту С++ подписанный char гарантированно сможет хранить значения от -127 до 127 (не -128!), Тогда как unsigned char способный удерживать значения от 0 до 255.
При преобразовании char в int результат определяется реализацией! результат может, например, be -55 или 201 в соответствии с реализацией машины одиночного char 'É' (ISO 8859-1). Действительно, процессор, содержащий char в слове (16 бит), может либо хранить FFC9, либо 00C9, либо C900, или даже C9FF (в больших и маленьких представлениях). Использование подписанных или неподписанных char действительно гарантирует результат преобразования char в int.