C++11 типов данных путаница
Я пытаюсь написать надежную сводку для типов данных C++, но у меня есть некоторая путаница с новыми типами данных.
Как я понял из моих чтений о типах данных C++, char16_t
а также char_32_t
являются фундаментальными типами данных и частью основного языка начиная с C++11.
Упоминается, что это разные типы данных.
Q1: Что именно означает "отдельный" здесь?
Q2: почему intxx_t
типа семья как int32_t
был выбран, чтобы не быть основным типом данных? И как они могут быть полезны при выборе их вместо int
?
3 ответа
Чтобы ответить на вторую часть вопроса:
Целочисленные типы фиксированного размера наследуются от C, где они typedef
s. Было решено оставить их как typedef
s быть совместимым. Обратите внимание, что язык C не имеет перегруженных функций, поэтому потребность в "различных" типах здесь ниже.
Одна из причин использования int32_t
является то, что вам нужно одно или несколько из его обязательных свойств:
Целочисленный тип со знаком с шириной ровно 32 бита без битов заполнения и с добавлением 2 для отрицательных значений.
Если вы используете int
это может быть, например, 36 бит и использовать дополнение 1.
Однако, если у вас нет особых требований, используйте обычный int
будет работать нормально. Одним из преимуществ является то, что int
будет доступен во всех системах, в то время как 36-битный компьютер (или 24-битный встроенный процессор) может не иметь int32_t
совсем.
charXX_t
типы были введены в N2249. Они созданы как отдельный тип uintXX_t
разрешить перегрузку:
определять
char16_t
быть отличным новым типом, который имеет тот же размер и представление, что иuint_least16_t
, Аналогично, определитьchar32_t
быть отличным новым типом, который имеет тот же размер и представление, что иuint_least32_t
,[N1040 определено
char16_t
а такжеchar32_t
как typedefs дляuint_least16_t
а такжеuint_least32_t
, что делает невозможной перегрузку этих символов.]
Чтобы ответить на ваш Q1:
Различный тип означает std::is_same<char16_t,uint_least16_t>::value
равно false
,
Так что перегруженные функции возможны.
(Хотя нет никакой разницы в размерах, подписи и выравнивании.)
Другой способ выразить "отдельные типы" - создать две перегруженные функции для каждого типа. Например:
typedef int Int;
void f(int) { impl_1; }
void f(Int) { impl_2; }
Если вы попытаетесь скомпилировать фрагмент кода, содержащий обе функции, компилятор пожалуется на нарушение ODR: вы дважды пытаетесь переопределить одну и ту же функцию, поскольку их аргументы одинаковы. Это потому чтоtypedef
s не создает типов, а только псевдонимы.
Однако, когда типы действительно различны, обе версии будут рассматриваться компилятором как две разные перегрузки.