Compartilhar via


auto (C++)

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

Observação

O padrão do C++ define um significado original e um significado revisado para essa palavra-chave. Antes do Visual Studio 2010, a palavra-chave auto declara uma variável na classe de armazenamento automatic, ou seja, uma variável que tem tempo de vida local. A partir do Visual Studio 2010, a palavra-chave auto declara uma variável cujo tipo é deduzido da expressão de inicialização na declaração. A opção de compilador /Zc:auto[-] controla o significado da palavra-chave auto.

Sintaxe

autodeclaratorinitializer;

[](autoparam1, autoparam2) {};

Comentários

A palavra-chave auto direciona o compilador para usar a expressão de inicialização de uma variável declarada ou um parâmetro de expressão lambda 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:

  • Robustez: se o tipo da expressão for alterado, inclusive quando um tipo de retorno de função for alterado, ele simplesmente funcionará.

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

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

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

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

  • Você quer um tipo específico e nada mais vai fazer.

  • Em tipos auxiliares de modelo de expressão — por exemplo, (valarray+valarray).

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 referência 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 auto de inicialização pode tomar várias formas:

  • Sintaxe de inicialização universal, como auto a { 42 };.
  • Sintaxe de atribuição, como auto b = 0;.
  • Sintaxe de atribuição universal, que combina os dois formulários anteriores, como auto c = { 3.14159 };.
  • Inicialização direta ou sintaxe no estilo construtor, como auto d( 1.41421f );.

Para obter mais informações, consulte Inicializadores e exemplos de código mais adiante neste documento.

Quando auto é usado para declarar o parâmetro loop em uma instrução for baseada em intervalo, ele usa uma sintaxe de inicialização diferente, por exemplo, for (auto& i : iterable) do_action(i);. Para obter mais informações, consulte Instrução for baseada em intervalo (C++).

A auto palavra-chave é um espaço reservado para um tipo, mas não é em si um tipo. Portanto, a auto palavra-chave não pode ser usada em casts ou operadores como sizeof e (para C++/CLI) 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, confira Exemplos de expressões lambda.

Rastreamento de tipos de retorno

Você pode usar auto com o especificador de tipo decltype para ajudar a escrever bibliotecas do modelo. Use auto e decltype declare um modelo de função cujo tipo de retorno depende dos tipos de seus argumentos de modelo. Ou, use auto e decltype declare um modelo de função que encapsula uma chamada para outra função e, em seguida, retorna qualquer que seja o tipo de retorno dessa outra função. Para obter mais informações, consulte decltype.

Referências e qualificadores CV

Usando auto referências de drops, const qualificadores e volatile qualificadores. Considere o seguinte exemplo:

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

No exemplo anterior, myAuto é um int, não uma int referência, então a saída é 11 11, não como seria o caso se o qualificador de referência não 11 12 tivesse sido descartado por auto.

Dedução de tipo com inicializadores preparados (C++14)

O exemplo de código a seguir mostra como inicializar uma variável auto usando chaves. Observe a diferença entre B e C e entre A e 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;
}

Restriçõ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 auto palavra-chave não pode ser combinada com nenhum 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 parâmetro ou argumento de modelo não pode ser declarado com a auto palavra-chave.
C3535 Um método ou parâmetro de modelo não pode ser declarado com a auto palavra-chave.
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 Não é possível converter para um tipo declarado com a auto palavra-chave.
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, confira Declarações e Definições.
C3540, C3541 Os operadores sizeof e typeid não podem ser aplicados a um símbolo declarado com a auto palavra-chave.

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

Confira também

Palavras-chave
/Zc:auto (Deduzir tipo de variável)
Operador sizeof
typeid
operator new
Declarações e definições
Exemplos de expressões lambda
Inicializadores
decltype