4.11.2. Другие неявные преобразования

Кроме арифметических, существует еще несколько видов неявных преобразований, включая следующие.

Преобразование массива в указатель. В большинстве выражений, когда используется массив, он автоматически преобразуется в указатель на свой первый элемент.

int ia[10];   // массив из десяти целых чисел

int* ip = ia; // ia преобразуется в указатель на первый элемент

Это преобразование не происходит при использовании массива в выражении decltype или в качестве операнда операторов обращения к адресу (&), sizeof или typeid (который рассматривается в разделе 19.2.2). Преобразование не происходит также при инициализации ссылки на массив (см. раздел 3.5.1). Подобное преобразование указателя происходит при использовании в выражении типа функции, как будет описано в разделе 6.7.

Преобразование указателя. Существует несколько других преобразований указателя: постоянное целочисленное значение 0 и литерал nullptr могут быть преобразованы в указатель на любой тип; указатель на любой неконстантный тип может быть преобразован в void*, а указатель на любой тип может быть преобразован в const void*. Как будет продемонстрировано в разделе 15.2.2, существуют дополнительные преобразования указателя, относящиеся к типам, связанным наследованием.

Преобразование в тип bool. Существует автоматическое преобразование арифметических типов и типов указателя в тип bool. Если указатель или арифметическое значение — нуль, преобразование возвращает значение false; любое другое значение возвращает true:

char *cp = get_string();

if (cp) /* ... */     // true, если cp не нулевой указатель

while (*cp) /* ... */ // true, если *cp не нулевой символ

Преобразование в константу. Указатель на неконстантный тип можно преобразовать в указатель на соответствующий константный тип, то же относится и к ссылкам. Таким образом, если Т — тип, то указатель или ссылку на тип T можно преобразовать в указатель или ссылку на const Т (см. разделы 2.4.1 и 2.4.2).

int i;

const int &j = i;   // преобразовать в ссылку на const int

const int *p = &i;  // преобразовать неконстантный адрес в константный

int &r = j, *q = p; // ошибка: преобразование константы в не константу

                    // недопустимо

Обратное преобразование (устранение спецификатора const нижнего уровня) невозможно.

Преобразование, определенное типами класса. Тип класса может сам определять преобразования, которые компилятор применит автоматически. Компилятор применяет только одно преобразование типа класса за раз. В разделе 7.5.4 приведен пример, когда необходимо несколько преобразований, и он не работает.

В программах ранее уже использовались преобразования типов класса, когда символьная строка в стиле С использовалась там, где ожидался библиотечный тип string (см. раздел 3.5.5), а также при чтении из потока istream в условии.

string s, t = "a value"; // символьный строковый литерал преобразован

                         // в тип string

while (cin >> s)         // условие while преобразует cin в bool

Условие (cin >> s) читает поток cin и возвращает его же как результат. Условия ожидают значение типа bool, но оно проверяет значение типа istream. Библиотека IO определяет преобразование из типа istream в bool. Это преобразование используется автоматически, чтобы преобразовать поток cin в тип bool. Результирующее значение типа bool зависит от состояния потока. Если последнее чтение успешно, то преобразование возвращает значение true. Если последняя попытка потерпела неудачу, то преобразование возвращает значение false.