Sintaxe de Retorno Posterior (Trailing Return Types)
O C++11 introduziu uma nova forma de declarar o tipo de retorno de uma função, posicionando-o após a lista de parâmetros. Essa abordagem é particularmente útil em templates onde o tipo de retorno depende dos argumentos processados.
template <typename T, typename U>
auto somar_valores(T a, U b) -> decltype(a + b) {
return a + b;
}
Além de templates, essa sintaxe é aplicada em ponteiros de função e funções de encaminhamento (forwarding functions), garantindo maior clareza quando lidamos com tipos complexos.
Reforço na Segurança de Tipos com Enumerações
As enumerações tradicionais do C++ possuem deficiências críticas, como a poluição do escopo global e a conversão implícita perigosa para inteiros. O C++11 resolve isso com as enum class (Strongly-typed enums).
enum class NivelAcesso : uint8_t {
Baixo,
Medio,
Alto,
Critico
};
// Uso obrigando o escopo
NivelAcesso usuario = NivelAcesso::Medio;
As principais vantagens são o escopo restrito, a impossibilidade de conversão acidental para int e a capacidade de definir explicitamente o tipo subjacente (como char ou uint8_t), otimizando o uso de memória.
Gerenciamento Inteligente de Memória
O C++11 consolidou o uso de ponteiros inteligentes para mitigar vazamentos de memória (memory leaks), substituindo o antigo e problemático auto_ptr.
- unique_ptr: Estabelece posse exclusiva sobre um recurso. Não pode ser copiado, apenas movido.
- shared_ptr: Implementa contagem de referências. O recurso é liberado apenas quando o último ponteiro que o referencia é destruído.
- weak_ptr: Atua como uma referência "observadora" para um objeto gerenciado por
shared_ptr, sem incrementar o contador de referências, evitando ciclos de retenção (circular references).
Suporte Mínimo para Garbage Collection
Embora o C++ não possua um coletor de lixo (GC) nativo onipresente como o Java, a norma C++11 introduziu conceitos para suportar implementações de GC e garantir a segurança de ponteiros. A linguagem define o conceito de "derivação segura de ponteiros" (Safe Pointer Derivation).
Operações seguras incluem aritmética básica de ponteiros e conversões via static_cast. Operações como o uso de XOR em endereços de memória são consideradas inseguras para um coletor de lixo, pois podem ocultar a existência de um ponteiro ativo.
Para gerenciar áreas de memória que o GC deve ignorar ou considerar sempre "alcançáveis", o padrão oferece funções específicas:
// Define que um ponteiro não deve ser coletado
void declare_reachable(void* p);
// Reverte a declaração de alcance
template<class T> T *undeclare_reachable(T *p) noexcept;
Tuplas e Variadic Templates
As std::tuple permitem agrupar múltiplos valores de tipos distintos em um único objeto, expandindo o conceito de std::pair.
#include <tuple>
#include <string>
auto obter_dados_aluno() {
return std::make_tuple(101, "Alice", 9.5);
}
void exemplo_tupla() {
auto info = obter_dados_aluno();
int id = std::get<0>(info);
std::string nome = std::get<1>(info);
}
Complementando isso, os Variadic Templates permitem que funções aceitem um número arbitrário de argumentos sem perder a segurança de tipos, algo que as funções variádicas do C (como printf) não garantiam.
#include <iostream>
// Caso base para encerrar a recursão
void logger() {
std::cout << std::endl;
}
// Função variádica recursiva
template<typename T, typename... Args>
void logger(T primeiro, Args... restante) {
std::cout << primeiro << " ";
logger(restante...); // Expansão do pacote de argumentos
}
// Uso: logger("Erro:", 404, "Não Encontrado", 0.5);