Урок №62. Вывод типов: ключевое слово auto

  Юрий  | 

    | 

  Обновл. 21 Апр 2019  | 

 21271

 ǀ   3 

До C++11 ключевое слово auto было наименее используемым ключевым словом в C++. Из урока №48 мы уже знаем, что локальные переменные имеют автоматическую продолжительность (создаются в точке определения и уничтожаются в конце блока, в котором определены).

Ключевое слово auto использовалось для явного указания, что переменная должна иметь автоматическую продолжительность:

Однако, поскольку все переменные в новых версиях C++ по умолчанию имеют автоматическую продолжительность, и, если явно не указывать другой тип продолжительности, то ключевое слово auto стало лишним и, следовательно, устаревшим.

Вывод типов в C++11

В C++11 значение ключевого слова auto изменилось. Рассмотрим следующий стейтмент:

Если C++ и так знает, что 4.0 является литералом типа double, то зачем нам дополнительно указывать, что переменная x должна быть типа double? Правда, было бы неплохо, если бы мы могли указать переменной принять соответствующий тип данных, основываясь на инициализируемом значении?

Начиная с C++11, ключевое слово auto при инициализации переменной может использоваться вместо типа переменной, чтобы сообщить компилятору, что он должен присвоить тип переменной исходя из инициализируемого значения. Это называется выводом типа (или ещё «автоматическим определением типа данных компилятором»). Например:

Это даже работает с возвращаемыми значениями функций:

Обратите внимание, это работает только с инициализируемыми переменными. Переменные, объявленные без инициализации, не могут использовать эту фичу (поскольку нет инициализируемого значения и компилятор не может знать, какой тип данных присвоить переменной).

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

Ключевое слово auto и параметры функций


Многие новички пытаются сделать что-то вроде следующего:

Это не сработает, так как компилятор не может определить типы данных для параметров функции a и b во время компиляции.

Если вы хотите создать функцию, которая будет работать с разными типами данных, вам лучше воспользоваться шаблонами функций, а не выводом типа. Это ограничение, возможно, отменят в будущих версиях C++ (когда auto будет использоваться как сокращённый способ создания шаблонов функций), но в C++14 это не работает. Единственное исключение — лямбда-выражения (но это уже другая тема).

Вывод типов в C++14

В C++14 функционал ключевого слова auto был расширен до автоматического определения типа возвращаемого значения функции. Например:

Так как выражение a − b типа int, то компилятор делает вывод, что и функция должна быть типа int.

Хотя это может показаться удобным, мы не советуем так делать. Тип возвращаемого значения функции помогает понять caller-у, что именно функция должна возвращать. Если конкретный тип не указан, то caller может неверно интерпретировать тип возвращаемого значения, что может привести к непреднамеренным ошибкам.

Так почему же использование auto при инициализации переменных — это хорошо, а с функциями — плохо? Дело в том, что auto можно использовать при определении переменной, так как значение, из которого компилятор делает выводы по типу переменной, находится прямо там, в правой части стейтмента. Однако с функциями это не так — нет контекста, который бы указывал, какого типа данных будет возвращаемое значение. Фактически пользователю придётся лезть в тело функции, чтобы определить тип возвращаемого значения. Следовательно, такой способ не только не практичен, но и более подвержен ошибкам.

Синтаксис trailing в C++11


В C++11 появилась возможность использовать синтаксис типа возвращаемого значения trailing (или просто «синтаксис trailing»), когда компилятор делает выводы о типе возвращаемого значения по конечной части прототипа функции. Например, рассмотрим следующее объявление функции:

В C++11 это можно записать как:

В этом случае auto не выполняет вывод типа — это всего лишь часть синтаксиса типа возвращаемого значения trailing. Зачем это стоит использовать? В основном из-за удобства. Например, можно выстроить в колонку все названия ваших функций:

Но этот синтаксис более полезен в сочетании с некоторыми другими продвинутыми особенностями C++, такими как классы и ключевое слово decltype. Мы поговорим подробнее о других использованиях auto, когда будем рассматривать ключевое слово decltype.

На данный момент мы рекомендуем придерживаться традиционного (обычного) синтаксиса для определения типа возвращаемого значения функции (без использования ключевого слова auto).

Заключение

Начиная с C++11, ключевое слово auto может использоваться вместо типа переменной при инициализации для выполнения вывода типа. Во всех других случаях, использование ключевого слова auto следует избегать, если на это нет веской причины.


Оценить статью:

Звёзд: 1Звёзд: 2Звёзд: 3Звёзд: 4Звёзд: 5 (121 оценок, среднее: 4,89 из 5)
Загрузка...

Комментариев: 3

  1. Аватар Torgu:

    за овер 60 уроков у меня сложилось несколько вопросу по плавающей точке:
    1. Почему вы все время используете double? Ведь точности того же float будет достаточно для большинства дробей
    2. В начале этого урока пишется, что "4.0" — литерал типа double. Почему double? Разве стандартный не float?
    3. В уроке о плавающей точке при инициализации переменной типа float вы добавляли f сразу после значения. Зачем? Ведь тип уже указан — float, зачем еще дополнительно что-то писать? Думал позже пойму, но нет, вот уже какой десяток уроков, до сих пор не догоняю

    1. Аватар Torgu:

      UPD: в итоге, сам ответил на свои вопросы 😉 Оказывается double стандартный тип для плавающей точки, а мне почему-то упорно казалось, что float. А фичу с постфиксом 'f' для чисел так и не понял

      1. Аватар Владимир:

        Добавление к константе постфикса f или F для float используется для повышения оптимизации, поскольку компилятор видит суффикс f и понимает, что это константа типа float, а не double. следовательно, не выполняется преобразование из double в float. А то, что тип double используется по умолчанию, говорилось ещё в уроке про литералы и магические числа (36 урок).

Добавить комментарий

Ваш E-mail не будет опубликован. Обязательные поля помечены *