Padrão C++26 aprovado

O Comitê ISO de padronização da linguagem C++ finalizou a versão final da especificação, que constitui o padrão internacional "C++26". Os recursos apresentados na especificação já são, em parte, suportados pelos compiladores GCC, Clang e Microsoft Visual C++. As bibliotecas padrão que dão suporte ao C++26 foram implementadas no âmbito do projeto Boost.

Nos próximos dois meses, a especificação aprovada estará em fase de preparação do documento para publicação, durante a qual serão realizados trabalhos de revisão para corrigir erros de ortografia e typos. No início de novembro, a versão resultante do documento será encaminhada ao ISO para publicação sob o nome formal ISO/IEC 14882:2026.

Principais características do C++26:

  • Foi implementado elementos de programação por contrato (Contracts), permitindo definir especificações formais de interfaces com o uso de três novos operadores: pre (pré-condição), post (pós-condição) e contract_assert (verificação de afirmação). O operador "pre" define as condições preliminares que devem ser atendidas antes da chamada (verificação dos dados de entrada); "post" – as condições que devem ser respeitadas após a execução (requisitos para os dados de saída); contract_assert – condições para o surgimento de exceções. Essa funcionalidade estará disponível no GCC 16. int f(const int x) pre (x != 1) // requisitos para os dados de entrada post (r : r == x && r != 2) // requisitos para o resultado; r é o valor do resultado { contract_assert (x != 3); return x; }
  • Foi adicionada suporte à reflexão (Reflection), permitindo rastrear e modificar elementos do programa em tempo de compilação. Novos operadores "^^" foram introduzidos para obter metainformação sobre a construção gramatical e "[:…:]" para realizar a transformação reversa. Para transformar e processar a informação obtida durante a inspeção, foi proposta a biblioteca std::meta que oferece funcionalidades como cálculos com constantes. O suporte à reflexão será adicionado no GCC 16. constexpr int i = 42, j = 42; constexpr std::meta::info r = ^^i, s = ^^i; static_assert(r == r && r == s); static_assert(^^i != ^^j); // 'i' e 'j' têm valores diferentes. static_assert(constant_of(^^i) == constant_of(^^j)); // 'i' e 'j' são iguais static_assert(^^i != std::meta::reflect_constant(42)); // difere do valor 42
  • Adicionado o operador «template for» para iterar sobre elementos, como pacotes de parâmetros, objetos semelhantes a tuplas e resultados de reflexão (metaojetos), na fase de compilação de maneira semelhante a um loop regular. Durante a execução do «template for», o corpo do loop é expandido para cada elemento e cada iteração é processada em um escopo separado, onde a variável que muda no loop é uma constante. No contexto da reflexão, o «template for» pode ser aplicado para percorrer as propriedades de classes ou enums. Essa funcionalidade estará disponível no GCC 16. void f() { template for (constexpr int I : std::array{1, 2, 3}) { static_assert(I < 4); } } será expandido para: void f() { { constexpr auto&& __range = std::array{1, 2, 3}; constexpr auto __begin = __range.begin(); constexpr auto __expansion_size = __range.end() — __begin; // 3 { constexpr int I = *(__begin + 0); static_assert(I < 4); } { constexpr int I = *(__begin + 1); static_assert(I < 4); } { constexpr int I = *(__begin + 2); static_assert(I < 4); } } }
  • Adicionado o framework std::execution para execução assíncrona e paralela de código. Objetos são fornecidos: scheduler, que define o planejador de execução (thread, pool de threads, GPU, loop de eventos), sender, que define o trabalho a ser executado, e receiver — o manipulador do resultado. using namespace std::execution; scheduler auto sch = thread_pool.scheduler(); sender auto begin = schedule(sch); sender auto hi = then(begin, []{ std::cout << "Hello world! Have an int."; return 13; }); sender auto add_42 = then(hi, [](int arg) { return arg + 42; }); auto [i] = this_thread::sync_wait(add_42).value();
  • Adicionada a biblioteca std::simd para paralelização da execução de operações sobre dados usando conjuntos de instruções SIMD, como AVX-512 e NEON, utilizando o sistema de tipos padrão do C++. std::simd a = {1.0f, 2.0f, 3.0f, 4.0f}; std::simd b = {5.0f, 6.0f, 7.0f, 8.0f}; std::simd result = a + b;
  • Proposta a implementação de um vetor (array) de tamanho variável std::inplace_vector, alocado na pilha, cujo tamanho é definido na fase de compilação. A API é semelhante à std::vector, mas os elementos do array são armazenados não em um "heap", mas dentro do objeto. inplace_vector a(10); inplace_vector b(std::move(a)); assert(a.size() == 10);
  • Adicionada a diretiva «#embed», destinada à incorporação de recursos binários no código. const unsigned char icon_display_data[] = { #embed "art.png" };
  • Adicionada suporte para geração e tratamento de exceções na fase de compilação em caso de erros no contexto constexpr. constexpr std::optional checked_divide(unsigned n, unsigned d) { try { return divide(n, d); } catch (…) { return std::nullopt; } } constexpr date parse_date(std::string_view input) { auto [correct, year, month, day] = ctre::match(input); if (!correct) { throw incorrect_date{input}; } return build_date(year, month, day); }
  • Implementada a estrutura de dados std::hive para armazenamento não ordenado de dados e para a reutilização de memória liberada após a remoção de elementos. A estrutura é otimizada para cargas com alta intensidade de adição e remoção de elementos em ordem arbitrária. Ao contrário de arrays, a remoção de um elemento em std::hive não causa o deslocamento de outros elementos, mas resulta na marcação do elemento removido como vazio, com subsequente preenchimento da posição liberada ao adicionar um novo elemento.
  • Adicionada a biblioteca std::linalg com API para álgebra linear, baseada em BLAS.
  • Adicionada suporte ao mecanismo de sincronização Hazard pointer, que permite evitar a liberação da memória de objetos que ainda estão em uso por outras threads sem a necessidade de bloqueios. Ao remover um objeto, ele é apenas marcado como removido, mas a memória ocupada pelo objeto é liberada somente quando todas as threads removem o hazard-pointer definido durante a operação com o objeto.
  • Adicionada suporte ao mecanismo de sincronização RCU (Read-Copy Update) — nas operações de gravação, um novo objeto é criado, enquanto as operações de leitura não são bloqueadas e continuam a funcionar com o antigo. Após a conclusão da modificação, o novo objeto se torna ativo e novas operações de leitura são realizadas com ele, enquanto o antigo é removido após a conclusão das threads que o estavam lendo.
  • Alterações foram feitas para aumentar a segurança da biblioteca padrão, como verificações de valores aceitáveis e saídas de limites de buffer. Por exemplo, ao acessar o elemento "constexpr reference operator[](size_type idx) const;" é adicionada uma verificação da condição "idx < size()".
  • Possibilitada a utilização da palavra-chave "constexpr" com uma variante do operador "new" (placement new) para alocar um objeto em memória previamente alocada durante a compilação.
  • Foi adicionado suporte a vínculos estruturados (structured binding) no contexto de «constexpr», ou seja, referências a expressões constantes agora podem ser expressões constantes. O suporte foi implementado para arrays e estruturas simples. constexpr int arr[] = {1, 2}; constexpr auto [x, y] = arr;
  • Nos vínculos estruturados, foi adicionada a possibilidade de usar a sintaxe «…» para indicar pacotes (pack) que capturam o restante dos elementos da sequência atribuída. auto [x,y,z] = f(); // as variáveis x, y, z receberão os três elementos retornados por f(). auto […xs] = f(); // o pacote xs receberá todos os elementos retornados por f(). auto [x, …rest] = f(); // x receberá o primeiro elemento, e rest os demais. auto [x, y, …rest] = f(); // x receberá o primeiro elemento, y o segundo, e rest o terceiro. auto [x, …rest, z] = f(); // x será o primeiro, rest o segundo, e z o terceiro.
  • Foi adicionado suporte à «movibilidade trivial» dos tipos (Trivial Relocatability), permitindo otimizar a movimentação de objetos de um determinado tipo por meio de sua clonagem na memória, sem a chamada de construtores ou destrutores. Para classes, foram implementadas as propriedades memberwise_trivially_relocatable e memberwise_replaceable, e para a movimentação de baixo nível de um ou mais objetos, foram adicionadas as funções trivially_relocate_at e trivially_relocate.
  • Foi implementado o suporte à anexação da função main() ao módulo global e à definição da função main() em módulos nomeados.
  • Foi adicionado o operador variático «friend» («friend Ts…»).
  • Foram implementados atributos para vínculos estruturados;
  • Foi adicionada a sintaxe ‘= delete(«razão»)’.
  • O conjunto básico de caracteres agora inclui «@», «$» e «`».
  • Foi proporcionada a possibilidade de aplicar vínculos estruturados (structured binding) como condição nos operadores if e switch.
  • Foi adicionada a possibilidade de usar várias variáveis de preenchimento com o nome «_» em um único escopo, por exemplo, as seguintes construções agora são válidas: struct S { int _, _; }; void func() { int _, _; } void other() { int _; // anteriormente, um aviso era gerado no modo -Wunused }
  • Foi possibilitado o uso de literais de string em contextos onde não são usados para inicializar um array de caracteres e não entram no código resultante, sendo aplicados apenas durante a compilação para mensagens de diagnóstico e pré-processamento, por exemplo, como parâmetros de diretivas e atributos _Pragma, asm, extern, static_assert, [[deprecated]] e [[nodiscard]].
  • Funções embutidas adicionadas: «__builtin_is_within_lifetime» para verificar a atividade de alternativas em uniões (union) e «__builtin_is_virtual_base_of» para verificar se uma classe base é virtual.
  • Implementados laços triviais infinitos sem comportamento indefinido.
  • Erro garantido ao remover um ponteiro de tipo incompleto.
  • O sintaxe de definição de parâmetros variádicos com reticências sem vírgula anterior foi declarado obsoleto (por exemplo, ao especificar "void e(int…)" em vez de "void e(int, …)").
  • O uso de macros para declarar módulos foi proibido.
  • Convertido para obsoleto a execução de conversões implícitas de valores enumerados em cálculos aritméticos. int main() { enum E1 { e }; enum E2 { f }; bool b = e <= 3.7; // obsoleto int k = f — e; // obsoleto int x = +f — e; // OK }
  • Suporte para comparação direta de arrays encerrado. int arr1[5]; int arr2[5]; bool same = arr1 == arr2;
  • A classe template is_trivial foi declarada obsoleta.

    Fonte: opennet.ru
Compre hospedagem confiável para sites com proteção contra DDoS, servidores VPS VDS 🔥 Compre hospedagem confiável para sites com proteção contra DDoS, servidores VPS VDS | ProHoster