>char
, a >const pstring
— это константный указатель на тип >char
, но не указатель на тип >const char
.Заманчиво, хоть и неправильно, интерпретировать объявление, которое использует псевдоним типа как концептуальную замену псевдонима, соответствующим ему типом:
>const char *cstr = 0; // неправильная интерпретация const pstring cstr
Однако эта интерпретация неправильна. Когда используется тип >pstring
в объявлении, базовым типом объявления является тип указателя. При перезаписи объявления с использованием >char*
, базовым типом будет >char
, а >*
будет частью оператора объявления. В данном случае базовый тип — это >const char
. Перезапись объявляет >cstr
указателем на тип >const char
, а не константным указателем на тип >char
.
>auto
>auto
. В отличие от таких спецификаторов типа, как >double
, задающих определенный тип, спецификатор auto приказывает компилятору вывести тип из инициализатора. Само собой разумеется, у переменной, использующей спецификатор типа >auto
, должен быть инициализатор.
>// тип item выводится из типа результата суммы val1 и val2
>auto item = val1 + val2; // item инициализируется результатом val1 + val2
Здесь компилятор выведет тип переменной >item
из типа значения, возвращенного при применении оператора >+
к переменным >val1
и >val2
. Если переменные >val1
и >val2
— объекты класса >Sales_item
(см. раздел 1.5), типом переменной >item
будет класс >Sales_item
. Если эти переменные имеют тип >double
, то у переменной >item
будет тип >double
и т.д.
Подобно любому другому спецификатору типа, используя спецификатор >auto
, можно определить несколько переменных. Поскольку объявление может задействовать только один базовый тип, у инициализаторов всех переменных в объявлении должны быть типы, совместимые друг с другом.
>auto i = 0, *p = &i; // ok: i - int, а p - указатель на int
>auto sz = 0, pi = 3.14; // ошибка: несовместимые типы у sz и pi
>const
и >auto
Выводимый компилятором тип для спецификатора >auto
не всегда точно совпадает с типом инициализатора. Компилятор корректирует тип так, чтобы он соответствовал обычным правилам инициализации.
Во-первых, как уже упоминалось, при использовании ссылки в действительности используется объект, на который она ссылается. В частности, при использовании ссылки как инициализатора им является соответствующий объект. Компилятор использует тип этого объекта для выведения типа >auto
.
>int i = 0, &r = i;
>auto a = r; // a - int (r - псевдоним для i, имеющий тип int)
Во-вторых, выведение типа >auto
обычно игнорирует спецификаторы >const
верхнего уровня (см. раздел 2.4.3). Как обычно в инициализациях, спецификаторы >const
нижнего уровня учитываются в случае, когда инициализатор является указателем на константу.