O que é auto em C++? Uma explicação direta ao ponto

Auto em C++: explicação direta ao ponto com robô ao lado.

A palavra-chave auto em C++ permite ao compilador fazer uma inferência de tipo, isto é, detectar automaticamente qual é o tipo da expressão que vem depois dela. Assim sendo, o auto permite, por exemplo, que o compilador detecte automaticamente o tipo de um variável.

Essa capacidade do auto torna-se especialmente útil quando o tipo da variável que se deseja inicializar é complicado de se escrever, como o tipo de it no exemplo 1 (ao invés de escrever vector<int>::iterator, escrevi apenas auto).


Exemplo 1 – Dedução simples usando auto em C++

#include <iostream>
#include <string>
#include <vector>

using namespace std;

int main()
{
    vector<int> iVec {10, 20, 30};
    auto it = iVec.begin(); // auto dispensa escrever o tipo vector<int>::iterator
    auto x {22.5};
    cout << "Tipo de x: " << typeid(x).name() << endl;
    cout << "Tipo de it: " << typeid(it).name() << endl;
}

Tipo de x: d
Tipo de it: N9__gnu_cxx17__normal_iteratorIPiSt6vectorIiSaIiEEEE

Como podemos ver na saída do exemplo acima, o tipo de x foi deduzido como double e o tipo de it como vector<int>::iterator (ainda que o seu nome na saída do programa seja difícil de se ler).


Referências e const com auto em C++

Apesar de permitir que o compilador deduza o tipo das variáveis corretamente, é importante notar que auto remove todos os indicadores de referência (&) e todos os const dos tipos deduzidos. Ou seja, se desejamos criar uma variáveis constante ou uma referência, é preciso adicionar manualmente const e & ao auto.

Vejamos um exemplo desse uso do auto a seguir.


Exemplo 2 – Referências e const removidos com auto em C++

#include <iostream>
#include <string>

using namespace std;

const string mensagem {"Oi, meu chapa"};

const string& obterMensagem() {
    return mensagem;
}

int main()
{
    auto x { obterMensagem() }; // Tipo de x: string
    const auto& y { obterMensagem() }; // Tipo de y: const string &
}

No exemplo 2, a variável x é criada a partir do retorno da função obterMensagem(), que retorna uma referência constante para a variável global mensagem. Todavia, o tipo de x é apenas string, visto que o auto remove o const e a referência do tipo deduzido.

Para obter o tipo const string& usando auto, eu tive que manualmente adicionar esses indicadores ao auto (linha 15, exemplo 2).

auto remove os indicadores const e de referência (&). Portanto, se quiser criar variáveis desses tipos usando auto, adicione os indicadores manualmente.


Ponteiros com auto em C++

Ao contrário do que acontece com const e referências, auto não remove o * dos tipos ponteiros, ou seja, auto detecta corretamente os tipos ponteiros simples. Assim, a variável y a seguir tem o tipo correto de int*.

int x {10};
auto y = &x;

Todavia, a dedução de tipos ponteiro com auto apenas (sem adicionar-lhe nada) escode uma pegadinha quando se deseja criar ponteiros para tipos constantes (por exemplo, const int * – ponteiro para int constante). Ao invés de deduzir que o tipo é const, auto deduz que o ponteiro é const! Para revisar os diferentes tipos de ponteiros, visite nosso artigo sobre o assunto.

Vejamos esse efeito no exemplo 3.


Exemplo 3 – Ponteiros e auto em C++

#include <iostream>
#include <string>

using namespace std;

int main()
{
    const int x { 10 };
    auto iPtr { &x }; // int*
    const auto iConstPtr { &x }; // int* const
    auto const iConstPtr2 { &x }; // int* const
    const auto* iPtrToConst { &x }; // const int * 
    auto* const iConstPtr3 { &x }; // int* const
    const auto* const iConstPtrToConst { &x }; // const int * const
}

No exemplo acima, vemos que a variável iConstPtr é do tipo int* const, isto é: ponteiro constante para int. Provavelmente não era isso que você queria fazer, não é? Queremos um ponteiro para int constante. Veja ainda que não adianta mudar o const de lugar, como fiz com iConstPtr2: o resultado é sempre o mesmo, int* const.

Para se obter um const int*, é preciso adicionar manualmente o * na frente do auto, para indicar que o tipo deduzido é um ponteiro. Fazendo assim, é possível obter const int*, como em iPtrToConst (linha 12). Também é possível obter quaisquer variações que se deseje movendo o const de lugar, como vemos com iConstPtr3 e iConstPtrToConst.

A seguir está um resumo dos tipos de cada um dos ponteiros do exemplo 3.

Tipo na declaração da variávelTipo deduzido da variávelNome do tipo
auto iPtrint*ponteiro para int
const auto iConstPtrint* constponteiro constante para int
auto const iConstPtr2int* constponteiro constante para int
const auto* iPtrToConstconst int*ponteiro para int constante
auto* const iConstPtr3int* constponteiro constante para int
const auto* const iConstPtrToConstconst int* constponteiro const para int const
Resumo dos tipo deduzidos usando auto e auto* junto ao const.
Best practices

Sempre que for deduzir o tipo de um ponteiro com auto, use o indicador * para evitar confusões como aquelas mostradas na tabela acima.


Próximos assuntos

Chegamos ao fim deste artigo, e eu espero que você tenha entendido como funciona a palavra-chave auto na dedução automática de tipos de variáveis, e que você tenha ficado atento ao detalhes no uso do auto com variáveis de tipo constante, referência e ponteiros.

Os próximos passos no seu trajeto para dominar o uso do auto em C++ é entender como ele funciona para se deduzir tipos de retorno de funções template, e como utilizá-lo em conjunto com o decltype.

Se não quiser perder esses artigos e ficar de olho no que postamos aqui, se inscreva na nossa newsletter para receber os artigos direto no seu email (você pode se desinscrever quando quiser).

Até à próxima!

Foto de perfil de Emanoel

Sou apaixonado por tecnologia, literatura e também filosofia. O cultivo dessas paixões ao longo da minha trajetória me inspiraram a compartilhar aquilo que aprendo com os outros da maneira mais clara que eu possa. Sou formado em Engenharia Elétrica no Brasil, e também sou engenheiro formado na França. Trabalho atualmente como programador C++ em uma multinacional francesa, uma das maiores empresas de TI do mundo.

Leave a Reply

Your email address will not be published. Required fields are marked *