Поделиться через


auto (C++)

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

Примечание.

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

Синтаксис

autoописатель Инициализатор ;

[](autoparam1 , 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 <iostream>

using namespace std;

int main( )
{
    int count = 10;
    int& countRef = count;
    auto myAuto = countRef;

    countRef = 11;
    cout << count << " ";

    myAuto = 12;
    cout << count << endl;
}

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

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

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

#include <initializer_list>

int main()
{
    // std::initializer_list<int>
    auto A = { 1, 2 };

    // std::initializer_list<int>
    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<int,list<string>>::iterator i = m.begin();
auto i = m.begin();

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

// cl /EHsc /nologo /W4
#include <deque>
using namespace std;

int main()
{
    deque<double> dqDoubleData(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;
    //...
}

См. также

Ключевые слова
/Zc:auto (Тип переменной Deduce)
Оператор sizeof
typeid
operator new
Объявления и определения
Примеры лямбда-выражений
Инициализаторы
decltype