C ++ авто ключевое слово.Почему это волшебство? - PullRequest
125 голосов
/ 28 сентября 2011

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

Внезапно итераторы STL и все, что использует шаблоны, в 10 раз легче написать. Такое ощущение, что я использую «забавный» язык, такой как Python.

Где это ключевое слово было всей моей жизнью? Будете ли вы разбить мои мечты, сказав, что это исключительно для визуальной студии или не портативные?

Ответы [ 5 ]

125 голосов
/ 28 сентября 2011

auto было ключевым словом, которое C ++ «унаследовал» от C, которое существовало там почти всегда, но практически никогда не использовалось, потому что было только два возможных условия: либо это было запрещено, либо предполагалось по умолчанию.

Использование auto для обозначения выведенного типа было новым для C ++ 11.

В то же время, auto x = initializer выводит тип x из типа initializer так же, как и вычитание типа шаблона для шаблонов функций. Рассмотрим шаблон функции следующим образом:

template<class T>
int whatever(T t) { 
    // point A
};

В точке A тип был присвоен T на основе значения, переданного параметру в whatever. Когда вы делаете auto x = initializer;, вычет того же типа используется для определения типа для x из типа initializer, который используется для его инициализации.

Это означает, что большинство механизмов вывода типов, которые компилятор должен реализовать auto, уже присутствовали и использовались для шаблонов в любом компиляторе, который даже пытался реализовать C ++ 98/03. Таким образом, добавление поддержки auto было, по-видимому, довольно простым для практически всех команд компиляторов - оно было добавлено довольно быстро, и, похоже, с этим также было связано несколько ошибок.

Когда этот ответ был изначально написан (в 2011 году, до того, как чернила высохли по стандарту C ++ 11), auto был уже достаточно портативным. В настоящее время он полностью переносим среди всех основных компиляторов. Единственными очевидными причинами, по которым этого следует избегать, может быть то, что вам нужно написать код, совместимый с компилятором C, или у вас есть особая необходимость нацелиться на какой-то специализированный компилятор, который, как вы знаете, не поддерживает его (например, несколько человек все еще пишут код для MS-DOS с использованием компиляторов Borland, Watcom и т. д., которые не обновлялись в течение десятилетий). Если вы используете достаточно актуальную версию какого-либо из распространенных компиляторов, нет никаких причин избегать ее вообще.

19 голосов
/ 28 сентября 2011

Он просто берет бесполезное ключевое слово и дает ему новую, лучшую функциональность.Это стандарт в C ++ 11, и большинство компиляторов C ++ даже с некоторой поддержкой C ++ 11 будут его поддерживать.

10 голосов
/ 28 сентября 2011

Эта функциональность не была там всю вашу жизнь. Он поддерживается в Visual Studio с версии 2010 года. Это новая функция C ++ 11, поэтому она не является эксклюзивной для Visual Studio и является / будет переносимой. Большинство компиляторов уже поддерживают это.

8 голосов
/ 30 июня 2016

Для переменных указывает, что тип объявленной переменной будет автоматически определяться из ее инициализатора. Для функций указывает, что тип возвращаемого значения является конечным типом возвращаемого значения или будет выведен из его операторов возврата (начиная с C ++ 14).

Синтаксис

auto variable initializer   (1) (since C++11)

auto function -> return type    (2) (since C++11)

auto function   (3) (since C++14)

decltype(auto) variable initializer (4) (since C++14)

decltype(auto) function (5) (since C++14)

auto :: (6) (concepts TS)

cv(optional) auto ref(optional) parameter   (7) (since C++14)

Объяснение

1) При объявлении переменных в области блока, в области пространства имен, в операторах инициализации циклов for и т. Д. Ключевое слово auto может использоваться в качестве спецификатора типа. Как только тип инициализатора определен, компилятор определяет тип, который заменит ключевое слово auto, используя правила для вывода аргумента шаблона из вызова функции (см. Подробности в разделе Вывод аргумента шаблона # Другие контексты). Ключевое слово auto может сопровождаться модификаторами, такими как const или &, которые будут участвовать в выводе типа. Например, если задано const auto& i = expr;, тип i точно соответствует типу аргумента u в воображаемом шаблоне template<class U> void f(const U& u), если вызов функции f(expr) был скомпилирован. Следовательно, auto && может быть выведено либо как ссылка lvalue, либо как ссылка rvalue в соответствии с инициализатором, который используется в цикле for на основе диапазона. Если auto используется для объявления нескольких переменных, выведенные типы должны совпадать. Например, объявление auto i = 0, d = 0.0; неправильно сформировано, в то время как объявление auto i = 0, *p = &i; правильно сформировано и auto выводится как int.

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

3) В объявлении функции, в котором не используется конечный синтаксис возвращаемого типа, ключевое слово auto указывает, что тип возвращаемого значения будет выведен из операнда оператора return с использованием правил для вывода аргумента шаблона.

4) Если объявленным типом переменной является decltype (auto), ключевое слово auto заменяется выражением (или списком выражений) его инициализатора, а фактический тип определяется с использованием правил для decltype.

5) Если тип возвращаемого значения функции объявлен decltype (auto), ключевое слово auto заменяется операндом его оператора return, а фактический тип возвращаемого значения выводится с использованием правил для decltype.

6) Спецификатор вложенного имени в форме auto :: - это заполнитель, который заменяется классом или типом перечисления в соответствии с правилами выведения заполнителя ограниченного типа.

7) Объявление параметров в лямбда-выражении. (начиная с C ++ 14) Объявление параметра функции. (понятия ТС)

Примечания До C ++ 11 auto имел семантику спецификатора продолжительности хранения. Смешивание автоматических переменных и функций в одном объявлении, как в auto f() -> int, i = 0;, не допускается.

Для получения дополнительной информации: http://en.cppreference.com/w/cpp/language/auto

3 голосов
/ 28 сентября 2011

Это никуда не денется ... это новая стандартная функция C ++ в реализации C ++ 11.При этом, хотя это замечательный инструмент для упрощения объявлений объектов, а также для очистки синтаксиса для определенных парадигм вызова (т. Е. Для циклов for на основе диапазона), не злоупотребляйте и не злоупотребляйте им: -)

...