Reflexão no C++26
Postado em 17/07/2026
Índice
Com a chegada do C++26, as propostas sobre reflexão em tempo de compilação que vinham sendo discutidas a algum tempo (ex: P2996, P3096, P3293, P3394, P3795), finalmente estão se tornando realidade, criando uma nova forma de se programar na linguagem. Na data de escrita deste artigo apenas o GCC 16 tem implementado o suporte experimental. No Clang ainda segue como planejado. Vamos explorar alguns casos de uso dessa funcionalidade.
Operadores novos
| Sintaxe | Nome | Significado |
|---|---|---|
^^entidade |
Operador de reflexão | Converte uma entidade C++ em std::meta::info. |
[: reflexão :] |
Splice | Converte uma reflexão novamente em código ou entidade C++. |
obj.[: membro :] |
Splice de membro | Acessa o membro descrito pela reflexão. |
[: tipo :] variável |
Splice de tipo | Usa o tipo descrito pela reflexão. |
[: valor :] |
Splice de expressão | Produz o valor ou entidade refletida. |
Obtendo o nome de um tipo
#include <meta>
#include <print>
struct Pessoa {
int idade;
};
int main() {
constexpr std::meta::info reflexao = ^^Pessoa;
std::println("{}", std::meta::identifier_of(reflexao));
return 0;
}Saída:
Pessoa
Percorrendo os campos de uma estrutura
#include <meta>
#include <print>
struct Pessoa {
int idade;
double altura;
bool ativo;
};
int main() {
constexpr auto contexto =
std::meta::access_context::current();
template for (
constexpr auto membro :
std::define_static_array(
std::meta::nonstatic_data_members_of(^^Pessoa, contexto)
)
) {
std::println("{}", std::meta::identifier_of(membro));
}
return 0;
}Saída:
idade
altura
ativo
Mostrar o nome e o tipo de cada campo
#include <meta>
#include <print>
struct Produto {
int codigo;
double preco;
bool disponivel;
};
int main() {
constexpr auto contexto =
std::meta::access_context::current();
template for (
constexpr auto membro :
std::define_static_array(
std::meta::nonstatic_data_members_of(^^Produto, contexto)
)
) {
constexpr auto tipo_do_membro =
std::meta::type_of(membro);
std::println(
"{}: {}",
std::meta::identifier_of(membro),
std::meta::display_string_of(tipo_do_membro)
);
}
return 0;
}Saída:
codigo: int
preco: double
disponivel: bool
Converter um enum para texto
#include <meta>
#include <print>
#include <string_view>
#include <type_traits>
enum class Cor {
vermelho,
verde,
azul
};
template <typename E>
requires std::is_enum_v<E>
constexpr std::string_view enum_para_texto(E valor) {
template for (
constexpr auto enumerador :
std::define_static_array(std::meta::enumerators_of(^^E))
) {
if (valor == [: enumerador :]) {
return std::meta::identifier_of(enumerador);
}
}
return "valor desconhecido";
}
int main() {
std::println("{}", enum_para_texto(Cor::vermelho));
std::println("{}", enum_para_texto(Cor::verde));
std::println("{}", enum_para_texto(Cor::azul));
return 0;
}Saída:
vermelho
verde
azul
Adicionando metadados tipados a elementos
#include <meta>
#include <print>
[[=42]]
int resposta;
consteval int valor_da_anotacao()
{
auto anotacoes =
std::meta::annotations_of(^^resposta);
return std::meta::extract<int>(anotacoes[0]);
}
static_assert(valor_da_anotacao() == 42);
int main()
{
constexpr int valor = valor_da_anotacao();
std::println("Anotação: {}", valor);
return 0;
}Saída:
Anotação: 42
Outros casos de uso
Além das demonstrações exibidas até agora, há uma variedade de outras possibilidades a se explorar. O Daniel Lemire fez uma ótima publicação em seu blog demonstrando a importância da reflexão ao se trabalhar com JSON e SQL.
Referência: cppreference