Seven of Eleven

Sempre que uma linguagem de programação é assunto entre as pessoas (programadores), normalmente surgem coisas como críticas e qualidades, muitas vezes a preferência de cada um é destacado nessa ou naquela funcionalidade – sem contar quando o assunto é esta ou aquela linguagem de programação esse tipo de discussão torna-se acalorada na maioria das vezes.

Durante o ano de 2013, tive a oportunidade de participar de alguns e eventos e palestrar sobre minha linguagem favorita: C++.

Na maioria dos eventos que participei e abordei o assunto desta linguagem de programação, o tema foi relacionado principalmente a C++ 11 (a versão padrão atual) e, a vezes, sobre a próxima versão, C++ 14 – onde o documento atual (Working Draft, Standard for Programming Language C++) é o N3797 datado em 13 de Outubro de 2013, e contempla C++ 11, bem como, o que será o futuro do C++.

seven_eleven

Sintetizo aqui as minhas 7 funcionalidades favoritas presentes no C++ 11. Essas conveniências da linguagem tornam o C++ mais elegante e simples de aprender e/ou ensinar.  O objetivo é apresentar a funcionalidade, onde ela é encontrada no documento padrão e a qual a motivação pela escolha.

Lambda: 5.1.2 Lambda expressions [expr.prim.lambda] [5. Expressions [expr]]

Lambda Expressions, é um recurso da linguagem, como o próprio padrão denota, que fornece uma maneira concisa para criar objetos do tipo função (ou functors). É possível declarar e aplicar um lambda diretamente numa função ou método que tem como parâmetro um functor. Em destaque alguns exemplos do uso do lambda.

lambda expression

Motivação: Gosto desta funcionalidade pelo simples fato dela possuir um relacionamento com o que estamos acostumados na programação funcional. Ela permite a criação de high-order functions, funções que tem como parâmetro ou retorno pelo menos uma função. Além disso, ela minimiza, se não elimina completamente, a aplicação em cenários onde eram necessários o uso de std::bind1st (obsoleta no C++ 11) ou similar. Ela também suporta o conceito de closure através da lista de captura (uma lista de argumentos que é indicada entre colchetes), diferente de outras linguagens de programação, é possível determiner a granularidade da captura, onde é possível definir se será por cópia ou por referência.

Range for: 6.5.4 The range-based for statement [stmt.ranged] [6. Statements [stmt.stmt]]

O range-for é outra conveniência para iterar containers ou qualquer coisa que um par de iterators begin e end.

range-for

Motivação: Talvez aqui pode ser aplicado o slogan: “do more with less”. A grande vantagem do range-for é a sua simplicidade para iteração, sem a verbosidade dos iterators. É fácil notar a similaridade com o for do Java, do Scala e do Python ou foreach do C# para iterar coleções para nomear alguns exemplos.

Alias: 7.1.3 The typedef specifier [dcl.typedef] [7. Declarations [dcl.dcl]]

O objetivo do using, neste caso, é oferecer uma extensão para as capacidades do typedef e permitir a criação de alias paramétricos, ou seja, alias com suporte ao mecanismo de templates.

using alias

Motivação: Gosto de utilizar a funcionalidade de alias, em qualquer linguagem de programação, para renomear algum conceito para uma coisa mais significativa e/ou seja mais rápido na digitação. E aqui não é diferente.

Type inference: 7.1.6.4 auto specifier [dcl.spec.auto] [7. Declarations [dcl.dcl]]

O auto permite a inferência de um tipo. Isto ocorrerá em tempo de compilação, ou seja, o compilador tentará deduzir o tipo de dado e substituí-lo pelo tipo apropriado ou até mesmo substituido por um tipo especificado após os tokens: ->.

auto type inference

Motivação: Inferência de tipo é um ótimo recurso quando o tipo a ser deduzido é óbvio ou seu uso contextual não for muito extenso (como no caso de a dedução do tipo de um iterator via begin ou cbegin, por exemplo). Gosto de usá-lo onde não há impacto que poderá levar a uma confusão, como por exemplo, em casos de polimorfismo, onde prefiro usar um tipo explícito.

Initializer list: 8.5.4 List-initialization [dcl.init.list] [8. Declarators [dcl.decl]]

A lista inicializadora permite seu tipo receber um lista arbitrária de elementos. No entanto, esta inicialização seguirá o padrão de inicialização uniforme proposta na nova versão de padrão do C++.

initializer list

Motivação: Tudo que é em prol da uniformidade para um código ser mantido é excelente. Esta é uma conveniência simples, porém fundamental para assegurar a uniformidade proposta.

Move semantics: 12.8 Copying and moving class objects [class.copy] [12. Special member functions [special]]

Move e copy semantics é uma dualidade. É muito comum copiar objetos em C++, as vezes isto gera uma inconveniência, ao qual poderá afetar o desempenho com excessivas sequências de criação de um novo objeto, a cópia dos dados do objeto antigo para o novo e a destruição do objeto antigo. A idéia de movimentar objetos é minimizar este overhead, principalmente quando o objeto antigo deve ser destruído. Normalmente, este comportamente ocorre na presença de objetos temporários – se um objeto temporário aparece a direita de uma atribuição (assignment), o compilador invocará uma operação de movimentação automaticamente, ao invés da cópia. A idéia presente nesta funcionalidade é de transferência de propriedade dos dados (transfer of data ownership). A diferença entre copiar e mover, e o que deve ser feito é apresentado no exemplo a seguir:

move_1_of_3

move_2_of_3

move_3_of_3

Motivação: Como me disseram uma vez, esta funcionalidade já justifica mudar do C++ 98 (ou C++ 03) para o C++ 11 – concordo plenamente! É possível “forçar” a invocação de um move constructor ou move assignment através do std::move.

Variadic templates: 14.5.3 Variadic templates [temp.variadic] [14. Templates [temp]]

Variadic templates é forma arbitrária de permitir 0 ou mais argumentos em templates ou em funções.

variadic templates

Motivação: A grande vantagem dos variadic templates é a possibilidade de escrever funções que emulem o comportamento de um “printf”, só que em tempo de compilação. Ou templates que atuem genericamente para uma grande quantidade de parâmetros e tipos distintos. Por exemplo, o std::tuple da biblioteca padrão é implementado com este recurso.

Finalizando

Bom, aqui é apresentado uma versão sintetizada de 7 conveniências do C++ 11 de minha preferência. Optei por colocar códigos de simples entendimento ao invés de uma quantidade de texto explicativos sobre o recurso. Para uma tour mais detalhada sobre estes assuntos recomendo:  A Tour of C++ de Bjarne Stroustrup.

Os slides da última palestra que ministrei em 2013 pode ser encontrada no endereço: C++ 11 e o Futuro do C++.

Acesse o código fonte completo aqui: http://bit.ly/1dUx5lY.

Versão PDF deste Post

About Fabio Galuppo

I'm Software Engineer and Professional Trainer. I love Programming and Rock'n'Roll.
This entry was posted in C++. Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s