Compartilhar via


Palavra-chave auto (dedução de tipo)

Deduz o tipo de uma variável declarada da expressão de inicialização.

auto declarator initializer;

Comentários

A palavra-chave auto direciona o compilador para usar a expressão de inicialização de uma variável declarada para deduzir o tipo.

Recomendamos que você use a palavra-chave auto para a maioria das situações, a menos que você realmente deseje uma conversão, pois ela fornece estes benefícios:

  • Vigor: se o tipo da expressão for modificado, e isso inclui a alteração de um tipo de retorno da função, ele apenas funciona.

  • Desempenho: você tem a garantia de que não haverá conversão.

  • Usabilidade: você não precisa se preocupar com dificuldades e erros de ortografia do nome do tipo.

  • Eficiência: a codificação pode ser mais eficiente.

Casos de conversão nos quais você pode não querer usar auto:

  • Quando você desejar um tipo específico e nada mais serve.

  • O auxiliar do modelo de expressão do tipo, como por exemplo, (valarray+valarray) e listas do inicializador, ainda que raramente você escolheria a gravação de auto x = { 1 }; e esperaria realmente obter int.

Para usar a palavra-chave auto, use-a em vez de um tipo para declarar uma variável e especifique uma expressão de inicialização. Além disso, você pode alterar a palavra-chave auto usando especificadores e declaradores como const, volatile, ponteiro (*), referência (&) e a referência de rvalue (&&). O compilador avalia a expressão e de inicialização e usa essas informações para deduzir o tipo da variável.

A expressão de inicialização pode ser uma atribuição (sintaxe de sinal de igualdade), uma inicialização direta (sintaxe de estilo de função), uma expressão do operador new ou a expressão de inicialização pode ser o parâmetro for-range-declaration em uma instrução Instrução for com base em intervalo (C++). Para obter mais informações, consulte Inicializadores e exemplos de código mais adiante neste documento.

A palavra-chave auto é um espaço reservado para um tipo, mas não é um tipo ela mesma. Portanto, a palavra-chave auto não pode ser usada nas conversões ou operadores como sizeof e typeID.

Utilidade

A palavra-chave auto é uma maneira simples de declarar uma variável que tenha um tipo complicado. Por exemplo, você pode usar auto para declarar uma variável onde a expressão de inicialização envolve modelos, ponteiros para as funções ou ponteiros para os membros.

Você também pode usar auto para declarar e inicializar uma variável em uma expressão lambda. Você não pode declarar o tipo da variável você mesmo pois o tipo de uma expressão lambda é conhecido apenas pelo compilador. Para obter mais informações, consulte Exemplos de expressões lambda.

Rastreamento de tipos de retorno

Você pode usar auto junto ao especificador de tipo decltype para ajudar a escrever bibliotecas do modelo. Use auto e decltype para declarar uma função de modelo cujo tipo de retorno dependa dos tipos dos argumentos de modelo. Ou, pode usar auto e decltype para declarar uma função do modelo que envolve uma chamada para outra função e então retorna o que for o tipo de retorno dessa outra função. Para obter mais informações, consulte Especificador de tipo decltype.

Referências e qualificadores CV

Observe que o uso de auto solta referências, qualificadores de constante e qualificadores voláteis. Considere o exemplo a seguir:

// 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;
}

Você pode acreditar que myAuto é uma referência int, mas não é. Ele simplesmente é um int, portanto o resultado é 11 11 e não 11 12, como seria o caso se a referência não tivesse sido solta por auto.

Limitações e mensagens de erro

A tabela a seguir lista as limitações no uso da palavra-chave auto e a mensagem de erro de diagnóstico correspondente, emitida pelo compilador.

Número do erro

Descrição

C3530

A palavra-chave auto não pode ser combinada com qualquer outro especificador de tipo.

C3531

Um símbolo que é declarado com a palavra-chave auto deve ter um inicializador.

C3532

Você usou incorretamente a palavra-chave auto para declarar um tipo. Por exemplo, você declarou um tipo de retorno do método ou matriz.

C3533, C3539

Um argumento de modelo ou parâmetro não pode ser declarado com a palavra-chave auto.

C3534

Um símbolo que é declarado com a palavra-chave auto em uma expressão new deve ter um inicializador. Para obter mais informações, consulte operador new (<new>).

C3535

Um parâmetro de modelo ou método não pode ser declarado com a palavra-chave auto.

C3536

Um símbolo não pode ser usado antes de ser inicializado. Na prática, isso significa que uma variável não pode ser usada para se inicializar.

C3537

Você não converter para um tipo que é declarado com a palavra-chave auto.

C3538

Todos os símbolos em uma lista de declaradores que são declarados com a palavra-chave auto devem ser resolvidos para o mesmo tipo. Para obter mais informações, consulte Declarações.

C3540, C3541

Os operadores sizeof e typeID não podem ser aplicados a um símbolo que é declarado com a palavra-chave auto.

Exemplos

Estes fragmentos de código ilustram alguns modos de uso da palavra-chave auto.

As declarações a seguir são equivalentes. Na primeira instrução, a variável j é declarada como tipo int. Na segunda instrução, a variável k é deduzida como sendo do tipo int pois a expressão de inicialização (0) é um inteiro.

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

As seguintes declarações são equivalentes, mas a segunda declaração é mais simples do que a primeira. Um dos motivos mais convincentes para o uso da palavra-chave auto é a simplicidade.

   map<int,list<string>>::iterator i = m.begin(); 
   auto i = m.begin(); 

O fragmento de código a seguir declara o tipo de variável iter e elem quando os loops de for e de for do intervalo são iniciados.

// 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
    { /* ... */ }
}

O fragmento de código a seguir usa a declaração do operador new e um ponteiro para declarar ponteiros.

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

O próximo fragmento de código declara vários símbolos em cada instrução de declaração. Observe que todos os símbolos em cada instrução são resolvidos para o mesmo tipo.

   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.

Esse fragmento de código usa o operador condicional (?:) para declarar a variável x como um inteiro com o valor de 200:

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

O fragmento de código a seguir inicializa a variável x para o tipo int, variável y para uma referência para um tipo const int, e variável fp para um ponteiro para uma função que retorna o tipo 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;
    //...
}

Consulte também

Referência

Palavra-chave auto

Especificadores de classe de armazenamento

Palavras-chave C++

/Zc:auto (deduzir tipo variável)

Operador sizeof

typeID

operador new (<new>)

Declarações

Exemplos de expressões lambda

Inicializadores

Especificador de tipo decltype