Ir para o conteúdo

Última atualização:2026-10-12

A família completa do const em C++

Sumário

  • const
  • constexpr
  • C++20
  • consteval
  • constinit

Nota: todos os exemplos de código deste artigo foram publicados no Planeta do Conhecimento.

1.const

const é uma das primeiras palavras-chave que conhecemos ao aprender C++/C; geralmente é usada como cv-qualifier, indicando que o objeto é imutável. Ela não garante a avaliação em tempo de compilação; o momento exato da avaliação fica a critério do compilador. Por exemplo:

const int a = 1; // 编译时
const auto x = getdata(); // 运行时

O const às vezes pode ser usado em expressões constantes em tempo de compilação, mas há exceções, por exemplo:

const double count_1 = 3.3;
std::array<double, static_cast<int>(count_1)> moreDoubles1 {1.1, 2.2, 3.3};

Nesse caso, ocorre o erro: the value of 'count_1' is not usable in a constant expression

Mas assim funciona normalmente:

const int count = 3;
std::array<double, count> doubles {1.1, 2.2, 3.3};

A essência está na avaliação de expressões em tempo de compilação; por isso, o C++11 introduziu o constexpr.

2.constexpr

constexpr pode ser usado para especificar que o valor de uma variável pode aparecer em uma expressão constante; basta trocar o const do exemplo anterior por constexpr para que ele funcione.

constexpr double count_2 = 3.3;
std::array<double, static_cast<int>(count_2)> moreDoubles2 {1.1, 2.2, 3.3}; 

constexpr não necessariamente só executa em tempo de compilação. Seu significado essencial é que pode ser calculado em tempo de compilação, mas se uma variável ou função constexpr for usada em tempo de execução, ela também pode ser executada em tempo de execução.

Por exemplo: result1 e result2 são completamente diferentes — result1 é calculado em tempo de compilação, mas result2 é calculado em tempo de execução. Fica a dúvida: você sabe por quê?

Portanto, não é porque uma função foi marcada com constexpr que ela será necessariamente calculada em tempo de compilação.

constexpr int compileTimeSum(int a, int b) {
    return a + b;
}

int main() {
    constexpr int result1 = compileTimeSum(3, 5); 
    int x = 10;
    int result2 = compileTimeSum(x, 20);  
    return 0;
}

Então, o que pode garantir isso? Foi então que chegou o C++20.

3.C++20

3.1 consteval

O consteval resolve o problema acima: ele só pode ser usado em funções e força todas as chamadas a acontecerem em tempo de compilação. Se trocarmos agora o constexpr do exemplo acima por consteval, o que acontecerá com result2?

Ocorrerá o erro: call to consteval function 'compileTimeSum(x, 20)' is not a constant expression

consteval int compileTimeSum(int a, int b) {
    return a + b;
}

int main() {
    constexpr int result1 = compileTimeSum(3, 5); 
    int x = 10;
    int result2 = compileTimeSum(x, 20);  
    return 0;
}

Se o consteval for usado em uma variável, também haverá erro: error: a variable cannot be declared 'consteval'.

https://en.cppreference.com/w/cpp/language/consteval

3.2 constinit

O constinit pode forçar a inicialização constante de variáveis estáticas ou de armazenamento local de thread.

  • Não pode ser usado junto com constexpr ou consteval
  • É um especificador não relativo a tipo, cuja função é fazer um assert
  • Garante que a variável seja estaticamente inicializada
  • Só pode ser aplicado a static ou thread_local

Por exemplo: o código a seguir gera erro de compilação: error: 'constinit' can only be applied to a variable with static or thread storage duration

constinit int a = 100;  
int main() {  
      ++a; 
      constinit auto b = 100;  // error
      // b has thread storage duration
      constinit thread_local auto b = 100;
}

Tópicos relacionados

Comentários