Última atualização:2026-10-12
constexpr e a expressão vírgula no C++20¶
constexpr e comma expr em C++那些事¶
O C++20 introduziu vários novos recursos, reforçando ainda mais as capacidades em tempo de compilação e a segurança do código. Este artigo explorará em profundidade duas mudanças importantes: o tratamento de exceções em funções constexpr e a descontinuação do operador vírgula dentro do operador de índice.
Obs.: versão para quem tem pressa, os exemplos de código e a documentação relacionada desta seção já foram atualizados no Planeta; junte-se se tiver interesse.
1. A mudança que passa a suportar try-catch em funções constexpr¶
Antes do C++20, não era possível usar blocos try-catch em funções constexpr; essa limitação impedia o processamento em tempo de compilação de alguns contêineres da biblioteca padrão, como std::array. O C++20 melhorou isso: passa a ser permitido usar blocos try-catch em funções constexpr, e essas estruturas de tratamento de exceções são ignoradas no contexto de expressões constantes. Quando uma exceção é lançada durante a avaliação de uma expressão constante, o compilador reporta um erro.
O principal objetivo dessa mudança é permitir que contêineres da biblioteca padrão, como std::array, ofereçam suporte a constexpr, além de estabelecer a base para dar suporte, no futuro, a mais tratamento de exceções em tempo de compilação.
Exemplo:
constexpr int SafeDivide(int a, int b) {
if (b == 0) {
throw std::runtime_error("Division by zero!"); // 当除数为0时抛出异常
}
return a / b;
}
constexpr int ComputeQuotient(int x) {
try {
return SafeDivide(100, x); // 尝试除法运算
} catch (const std::runtime_error&) {
return -1; // 捕获除零异常并返回 -1
}
}
O código acima não compila antes do C++20. Qual é o comportamento do C++20 nesse caso? Tente adivinhar os dois resultados a seguir:
2. Descontinuação do operador vírgula dentro do operador de índice¶
Outra mudança do C++20 é a descontinuação do uso do operador vírgula dentro do operador de índice. Em versões anteriores do C++, na expressão array[x, y], o operador vírgula fazia com que y fosse passado como índice ao array ou contêiner, enquanto x era ignorado. Contudo, esse uso torna o código difícil de entender e atrapalha uma futura implementação de arrays multidimensionais. Por isso, a partir do C++20, o operador vírgula dentro do operador de índice foi descontinuado, a menos que sejam usados parênteses para especificar explicitamente a precedência, como em array[(x, y)].
Código de exemplo:
Neste exemplo, arr[(i, j)] usa parênteses para deixar explícita a precedência do operador vírgula, garantindo que j seja passado como índice ao array. No C++17, arr[i, j] é permitido, mas no C++20 esse uso gera um aviso de descontinuação. Dessa forma, é possível garantir um comportamento consistente do código e em conformidade com o novo padrão do C++20.
Se o operador vírgula for usado, o compilador emitirá um aviso:
common.cc:9:10: warning: top-level comma expression in array subscript is deprecated [-Wcomma-subscript]
9 | arr[i, j] = 10; // C++17 中合法,C++20 中弃用
| ^
Resumo¶
As mudanças do C++20, em especial o suporte ao tratamento de exceções em funções constexpr e a descontinuação do operador vírgula no operador de índice, visam melhorar as capacidades em tempo de compilação e a legibilidade do código. Se o seu código depende desses recursos antigos, recomenda-se ajustá-lo em tempo hábil para se adaptar ao novo padrão do C++20.
Tópicos relacionados¶
- Introdução às corrotinas no C++20 | C++那些事
- Prática com channel no C++20 | C++那些事
- Concepts (conceitos) no C++20 | C++那些事
- Ordem de bytes (endian) no C++20 | C++那些事
- Expressões Lambda no C++20 (parte 1) | C++那些事
- Módulos (Modules) no C++20 | C++那些事
- Biblioteca Ranges do C++20 | C++那些事
- Design e armadilhas do std::span no C++20 | C++那些事
- Guia dos novos recursos do C++20 | C++那些事
- [[likely]] e [[unlikely]] no C++20 | C++那些事