Inferência de tipo no C++ moderno

Inferência de tipo é a dedução automática do tipo de dado a partir de uma expressão. No caso do C++ moderno a dedução é feita pelo compilador.

Os templates do C++ já possuiam um forma limitada de dedução de tipos, ou seja, você não precisa indicar o tipo de dado explicitamente como demonstrado no exemplo abaixo:

Note que ao chamar a função template display, ela não foi parametrizável, pois o mecanismo de templates soube deduzir T a partir do argumento indicado na chamada da função. Porém como indicado anteriormente,  a inferência via templates é limitada e não tem a mesma abrangência e usabilidade da inferência de tipos introduzidas no C++ moderno com auto e decltype.

Inferência de tipo com auto

A inferência no C++ é muito simples. Uma vez que você sabe declarar uma variável, basta substituir o tipo da variável pela palavra chave auto. O contéudo a direita da declaração, logo após a inicialização ou  atribuição,  é uma expressão (variável, chamada de função, …) que possui um tipo associado. O compilador utilizará a informação para “substituir” e indicar o valor da variável declarada com auto. Abaixo, três variáveis estão declaradas explicitamente com seus tipos e outras três utilizam auto para a dedução do tipo a partir da expressão a direita.

O problema ou caracteristica da dedução de tipos com auto é que os qualificadores para constante e referência são ignorados, apenas o tipo de dado é absorvido. No exemplo a seguir, a variável y1 não será constante, mas a variável y2 será constante.

Portanto, basta utilizar const e/ou & para qualificar a nova declaração:

A inferência de tipo também é uma conveniência para poupar os esforços de digitação ou deixar as declarações menos redundantes, como no caso de um container na forma de dicionário:

Inferência de tipo com decltype

Com decltype a utilização é similar ao auto, porém ela preserva as qualificações da expressão. É possível indicar uma expressão completa dentro do parâmetro de decltype.

No entanto, na maioria das vezes seu uso com expressão não é  tão conveniente devido a redundância que desejamos evitar. Imagine digitar algo assim:

decltype(e + e + e + e + e) a3 = (e + e + e + e + e);

Isso não parece ser simples.

O C++ 11 vai até aqui, o C++ 14 estende seu mecanismo de inferência de tipo e possui uma combinação dos benefícios de auto e decltype, como veremos a seguir.

Inferência de tipo com decltype(auto) do C++ 14

No C++ 14, decltype(auto) é a inferência de tipo em sua plenitude – além da dedução do tipo ela preservará suas qualificações como constante e/ou referência se este for caso. Abaixo, um exemplo de uso evitando certas redundâncias de notação:

Veja a seguinte função que gera uma const std::string aleatória:

O código acima utiliza inferência com auto em duas ocasiões:

  • No linha 8, onde o bind retornará um functor baseado no objeto do tipo função (outro functor) da distribuição informada no primeiro argumento;
  • Na linha 11,  como uma referência de char, para que seja possível a atribuição na próxima sequência.

Como se trata de uma função que retornará um valor constante, no consumo desta função, ao usarmos o decltype(auto) para declarar a variável que receberá o resultado desta computação, teremos a seguinte resposta:

Como referência, aqui estão as execuções do exemplo deste post compilados com clang++ (7.0.2 (clang-700.1.81)), g++ (g++ (GCC) 5.3.0) e cl (Microsoft (R) C/C++ Optimizing Compiler Version 19.00.23506 for x64) respectivamente, todos eles possuem suporte ao C++ 14:

inference_in_clang

inference_in_gcc

inference_in_msvc

Fontes:
https://github.com/SimplyCpp/examples/blob/master/understanding_inference_program.cpp

Anúncios

Deixe um comentário

Preencha os seus dados abaixo ou clique em um ícone para log in:

Logotipo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair / Alterar )

Imagem do Twitter

Você está comentando utilizando sua conta Twitter. Sair / Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair / Alterar )

Foto do Google+

Você está comentando utilizando sua conta Google+. Sair / Alterar )

Conectando a %s