Auto c что это
Перейти к содержимому

Auto c что это

  • автор:

auto (C++)

Выводит тип объявленной переменной из выражения инициализации.

Стандарт C++ определяет исходный и измененный смысл для этого ключевое слово. Перед Visual Studio 2010 auto ключевое слово объявляет переменную в классе автоматического хранения, то есть переменную, которая имеет локальное время существования. Начиная с Visual Studio 2010, ключевое слово объявляет переменную, auto тип которой выводится из выражения инициализации в объявлении. Параметр /Zc:auto[-] компилятора управляет значением auto ключевое слово.

Синтаксис

auto declaratorinitializer ;

[](auto param1 , auto param2 ) <>;

Замечания

auto Ключевое слово направляет компилятору использовать выражение инициализации объявленной переменной или лямбда-параметра выражения, чтобы вывести его тип.

Рекомендуется использовать auto ключевое слово для большинства ситуаций, если вы не хотите преобразовать, так как это дает следующие преимущества:

  • Надежность. Если тип выражения изменяется( включая изменение типа возвращаемого значения функции), он просто работает.
  • Производительность. Вы гарантируете, что преобразования отсутствуют.
  • Удобство использования: вам не нужно беспокоиться о проблемах орфографии имен типов и опечаток.
  • Эффективность: код может быть более эффективным.

Варианты преобразования, в которых может не потребоваться использовать auto :

  • Вы хотите конкретный тип и ничего другого не будет делать.
  • Например, (valarray+valarray) вспомогательные типы шаблонов выражений.

Чтобы использовать auto ключевое слово, используйте его вместо типа для объявления переменной и укажите выражение инициализации. Кроме того, можно изменить auto ключевое слово с помощью описателей и деклараторов, таких как const , volatile указатель ( * ), ссылка ( & ) и ссылка rvalue ( && ). Компилятор вычисляет выражение инициализации, а затем использует эти сведения, чтобы вывести тип переменной.

auto Выражение инициализации может принимать несколько форм:

  • Синтаксис универсальной инициализации, например auto a < 42 >; .
  • Синтаксис назначения, например auto b = 0; .
  • Синтаксис универсального назначения, который объединяет две предыдущие формы, например auto c = < 3.14159 >; .
  • Прямая инициализация или синтаксис стиля конструктора, например auto d( 1.41421f ); .

Дополнительные сведения см. в разделе «Инициализаторы» и примеры кода далее в этом документе.

Если auto используется для объявления параметра цикла в инструкции на основе for диапазона, он использует другой синтаксис инициализации, например for (auto& i : iterable) do_action(i); . Дополнительные сведения см. в инструкции на основе for диапазона (C++).

auto Ключевое слово — это заполнитель для типа, но он не является типом. auto Поэтому ключевое слово нельзя использовать в приведениях или операторах, таких как sizeof и (для C++/CLI). typeid

Удобство

auto Ключевое слово — это простой способ объявить переменную с сложным типом. Например, можно объявить auto переменную, в которой выражение инициализации включает шаблоны, указатели на функции или указатели на элементы.

Можно также использовать auto для объявления и инициализации переменной в лямбда-выражение. Вы не сможете самостоятельно объявить тип переменной, поскольку тип лямбда-выражения известен только компилятору. Дополнительные сведения см. в примерах лямбда-выражений.

Отслеживание возвращаемых типов

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

Ссылки и cv-квалификаторы

Использование auto ссылок, const квалификаторов и volatile квалификаторов. Рассмотрим следующий пример:

// cl.exe /analyze /EHsc /W4 #include using namespace std; int main( )

В предыдущем примере myAuto является не int ссылкой int , поэтому выходные данные 11 11 не 11 12 так, как было бы в случае, если квалификатор ссылок не был удален auto .

Вычет типов с фигурными инициализаторами (C++14)

В следующем примере кода показано, как инициализировать переменную auto с помощью фигурных скобок. Обратите внимание на разницу между B и C и между A и E.

#include int main() < // std::initializer_listauto A = < 1, 2 >; // std::initializer_list auto B = < 3 >; // int auto C< 4 >; // C3535: cannot deduce type for 'auto' from initializer list' auto D = < 5, 6.7 >; // C3518 in a direct-list-initialization context the type for 'auto' // can only be deduced from a single initializer expression auto E< 8, 9 >; return 0; > 

Ограничения и сообщения об ошибках

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

Номер ошибки Description
C3530 Ключевое слово auto нельзя сочетать с любым другим описательом типа.
C3531 Символ, объявленный с auto ключевое слово, должен иметь инициализатор.
C3532 Вы неправильно использовали auto ключевое слово для объявления типа. Например, был объявлен тип возвращаемого значения метода или массив.
C3533, C3539 Аргумент параметра или шаблона нельзя объявить с auto помощью ключевое слово.
C3535 Невозможно объявить метод или параметр шаблона с auto помощью ключевое слово.
C3536 Символ нельзя использовать перед инициализацией. На практике это означает, что переменная не может использоваться для инициализации себя.
C3537 Нельзя привести к типу, объявленному с auto помощью ключевое слово.
C3538 Все символы в списке декларатора, объявленные с auto помощью ключевое слово, должны разрешаться в один и тот же тип. Дополнительные сведения см. в объявлениях и определениях.
C3540, C3541 Операторы sizeof и typeid нельзя применять к символу, объявленному с auto помощью ключевое слово.

Примеры

Эти фрагменты кода иллюстрируют некоторые способы auto использования ключевое слово.

Следующие объявления эквивалентны. В первой инструкции переменная j объявляется типом int . Во втором операторе переменная k выводится в тип int , так как выражение инициализации (0) является целым числом.

int j = 0; // Variable j is explicitly type int. auto k = 0; // Variable k is implicitly type int because 0 is an integer. 

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

map>::iterator i = m.begin(); auto i = m.begin(); 

Следующий фрагмент кода объявляет тип переменных iter и elem при for запуске циклов диапазона for .

// cl /EHsc /nologo /W4 #include using namespace std; int main() < dequedqDoubleData(10, 0.1); for (auto iter = dqDoubleData.begin(); iter != dqDoubleData.end(); ++iter) < /* . */ >// prefer range-for loops with the following information in mind // (this applies to any range-for with auto, not just deque) for (auto elem : dqDoubleData) // COPIES elements, not much better than the previous examples < /* . */ >for (auto& elem : dqDoubleData) // observes and/or modifies elements IN-PLACE < /* . */ >for (const auto& elem : dqDoubleData) // observes elements IN-PLACE < /* . */ >> 

Следующий фрагмент кода использует new оператор и объявление указателя для объявления указателей.

double x = 12.34; auto *y = new auto(x), **z = new auto(&x); 

В следующем примере кода объявлено несколько символов в каждом операторе объявления. Обратите внимание, что все символы во всех операторах разрешаются к одному и тому же типу.

auto x = 1, *y = &x, **z = &y; // Resolves to int. auto a(2.01), *b (&a); // Resolves to double. auto c = 'a', *d(&c); // Resolves to char. auto m = 1, &n = m; // Resolves to int. 

В этом примере кода используется условный оператор ( ?: ). Переменная x здесь объявляется как целочисленная переменная со значением 200.

int v1 = 100, v2 = 200; auto x = v1 > v2 ? v1 : v2; 

Следующий фрагмент кода инициализирует переменную типа, переменную x int к типу const int и переменную fp y указателю на функцию, возвращающую тип int .

int f(int x) < return x; >int main() < auto x = f(0); const auto& y = f(1); int (*p)(int x); p = f; auto fp = p; //. >

Что такое auto в C++?

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

Основные моменты:

  1. Автоматическое выведение типа: auto позволяет компилятору самостоятельно определить тип переменной на основе ее инициализации.
  2. Удобство и читаемость: Использование auto делает код более кратким и читаемым, особенно в случаях, когда тип данных длинный или сложный.
  3. Обязательное присваивание значения: При использовании auto , переменной должно быть явно присвоено значение при инициализации.
int main() < // Использование auto для удобства объявления переменной auto sum = 0; for (const auto& num : numbers) sum += num; std::cout

Auto c что это

Ограничения типа также можно использовать для ограничения типов, вместо которых используются заменители auto , auto* и auto& . Причем везде, где используется auto, также можно указывать ограничение типа: для определения локальных переменных, для типа результат функции, в лямбда-выражениях и т. д. Всякий раз, когда конкретный тип, который будет применяться вместо auto , не удовлетворяет ограничению типа, компилятор выдает ошибку.

#include #include template concept Numeric = std::integral || std::floating_point; Numeric auto sum(Numeric auto a, Numeric auto b) < const Numeric auto result; return result; > int main() < std::cout 

Здесь определен концепт Numeric , который предполагает, что тип T должен представлять целое число ( std::integral ), либо число с плавающей точкой ( std::floating_point ).

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

Numeric auto sum

Для типа параметров

(Numeric auto a, Numeric auto b)

Для константы внутри функции

const Numeric auto result;

Затем можно вызывать эту функцию sum, передавая в нее числа, как целые, так и с плавающей точкой:

sum(10, 3) // 13 sum(10.6, 3.2) // 13.8

auto в C

Почему строка auto a = 1; воспринимается компилятором C как корректная?

Я пользуюсь MS Visual Studio 2012, и вот этот код:

int main(void)

компилируется без ошибок, несмотря на то, что я использую расширение *.c исходника. Т.е. таким образом, я создаю код на чистом C, а насколько мне известно использование auto без указания типа стало возможным только в C++11 – заметьте, в C++, а не C.

Означает ли это, что у меня не так настроен компилятор, или этот код действительно корректен в C?

Ответ

auto – это старое ключевое слово C, обозначающее “локальную область видимости”. auto a эквивалентно auto int a, а в силу того, что в данном примере область видимости ограничена блоком, в котором объявлена переменная, то это то же самое, что и просто int a.

Это ключевое слово перешло в C еще из его предка, B, в котором не существовало базовых типов, а все было int(*): сами int‘ы, указатели на них, массивы int‘ов и т.п. И объявлялось все с помощью auto и extern. Подход “все, что тут есть – это int” в C было решено оставить, поэтому int‘овые переменные можно объявить и так:

auto a; extern b; static c; 

В стандарте ISO C от подобного подхода отказались, однако многие компиляторы все еще поддерживают bacward-совместимость. Если это кажется вам странным, то вспомните о том, что вот такая строка будет корректной:

unsigned d; // на самом деле unsigend int 

В C++ это слово вернули, но уже с новым смыслом (теперь эта конструкция позволяет явно не указывать тип переменной), ведь вряд ли множество программистов использовало это слово с оригинальным значением, особенно если учесть, что от “всего, что ты видишь – это int” отказались уже в C++98. Единственным исключением осталось тогда auto T a, чем все равно никто не пользуется.

Если вам не лень и очень интересно, можете покопаться в истории языка за авторством Страуструпа.

Кстати, интересно было организовано хранение строк в B. Строка была массивом int‘ов, каждый элемент которого хранил несколько символов. Таким образом, B – это тот же BCPL с другим синтаксисом.

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

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