Skip to content

搞英语 → 看世界

翻译英文优质信息和名人推特

Menu
  • 首页
  • 作者列表
  • 独立博客
  • 专业媒体
  • 名人推特
  • 邮件列表
  • 关于本站
Menu

探索 C++26 的编译时反射

Posted on 2025-06-22

Herb Sutter 刚刚宣布结论:C++26,即 C++ 的下一个版本,将包含编译时反射。

编程语言中的反射意味着您可以访问代码自身的结构。例如,您可以获取一个类,并枚举其方法。例如,您可以接收一个类,检查它是否包含返回字符串的方法,然后调用此方法并获取字符串。大多数编程语言都支持某种形式的反射。例如,老牌的 Java 就完全支持反射。

然而,C++ 正在获得编译时反射。这是一个重要的发展。

几个月前,我宣布,由于与 Francisco Geiman Thiesen 的合作,只要主流编译器支持,性能导向的 JSON 库 simdjson 就会支持编译时反射。

这使得您可以采用自己的数据结构并将其转换为 JSON 字符串,而无需付出任何努力,而且速度很快:

孩子 k{12, "约翰", {"汽车", "球"}}; simdjson::to_json(k); // 将生成 {"age": 12, "name": "John", "toys": ["car", "ball"]} 

您还可以返回,给定一个 JSON 文档,您可以返回自定义类型的实例:

孩子 k = doc.get<kid>(); 

代码可以在主库中进行高度优化和全面测试。无需样板代码有诸多好处。

为了进一步说明这个想法,让我考虑一下对象到SQL映射的情况。假设你有一个自定义类型:

结构用户{ int id ; std ::字符串名称; 双平衡; 私人的: int secret ; // 在 SQL 生成中忽略 } ; 

你想把这个用户的实例插入到数据库中。你需要把它转换成如下字符串:

插入 tbl (id, name, balance) 值 (0, '', 0.000000);

这有多简单?通过编译时反射,我们可以实现高效且简单的单函数调用:

生成_sql_insert ( u , “表” ) ;

当然,繁重的工作仍需完成。但只需做一次。

它看起来像什么?首先,我们要生成列字符串(例如,id、name、balance)。

我还没有接触过真正的 C++26 编译器。C++26 正式发布后,我们会引入一些类似“template for”的功能,它类似于“for”循环,但用于模板元编程。同时,我使用了一种比较晦涩的“expand”语法。

代码仍然是合理的:

模板<类型名称T > consteval std :: string generate_sql_columns ( ) { std ::字符串列; bool first = true ;  constexpr auto ctx = std :: meta :: access_context :: current ( ) ;  [ :扩展( std :: meta :: nonstatic_data_members_of ( ^ ^ T , ctx ) ) : ]  > > [ & ] <自动成员> { 使用member_type = typename [ : type_of ( member ) : ] ; 如果( !第一个) { 列+ = “ , ” ; } 第一个=假;  // 获取会员名称 自动名称= std :: meta :: identifier_of (成员) ; 列+ =名称; } ;  返回列; } 

此函数是“consteval”函数,这意味着您应该期望它在编译时进行求值。因此它非常高效:字符串在编译代码时计算。因此,以下函数可能只返回一个预先计算的字符串:

 std ::字符串g ( ) { 返回generate_sql_columns <用户> ( ) ; } 

接下来我们需要计算这些值的字符串(例如,(0, ”, 0.000000))。这有点棘手。你需要转义字符串,并处理不同的值类型。这是一个不错的草图:

模板<类型名称T > constexpr std :: string generate_sql_valuess ( const T & obj ) { std ::字符串值; bool first = true ;  constexpr auto ctx = std :: meta :: access_context :: current ( ) ;  [ :扩展( std :: meta :: nonstatic_data_members_of ( ^ ^ T , ctx ) ) : ]  > > [ & ] <自动成员> { 使用member_type = typename [ : type_of ( member ) : ] ; 如果( !第一个) { 值+ = “ , ” ; } 第一个=假;  // 获取成员值 自动值= obj . [ : member : ] ;  // 根据类型格式化值 如果constexpr ( std :: same_as <成员类型, std :: string > ) { // 转义字符串中的单引号 std ::字符串转义=值; size_t位置= 0 ; while ( ( pos = escaped.find ( ' \ '' , pos ) )  ! = std :: string :: npos ) { 转义. replace ( pos , 1 , " ' ' ) ; 位置+ = 2 ; } 值+ = “ ' ” +转义+ “ ' ” ; }否则,如果constexpr ( std :: is_arithmetic_v < member_type > ) { 值+ = std :: to_string (值) ; } } ;  返回值; }

现在你可以把它们放在一起:

模板<类型名称T > constexpr std :: string generate_sql_insert ( const T & obj , const std :: string & table_name ) { constexpr std :: string列= generate_sql_columns < T > ( ) ; std ::字符串值= generate_sql_valuess ( obj ) ; 返回“ INSERT INTO ” +表名  + “ ( ” +列+ “ )值( ” +值+ “ ); ” ; } 

它只是众多应用之一。其核心思想是,你可以编写高度优化且非常安全的代码,这些代码可以在许多情况下重用。代码看起来有点吓人,就像 C++ 那样,但它相当合理。

在未来的几年里,许多项目将通过编译时反射得到简化和优化。

代码:我已经在我的博客代码库中发布了完整的实现。我相信它还能有显著的改进。

原文: https://lemire.me/blog/2025/06/22/c26-will-include-compile-time-reflection-why-should-you-care/

本站文章系自动翻译,站长会周期检查,如果有不当内容,请点此留言,非常感谢。
  • Abhinav
  • Abigail Pain
  • Adam Fortuna
  • Alberto Gallego
  • Alex Wlchan
  • Answer.AI
  • Arne Bahlo
  • Ben Carlson
  • Ben Kuhn
  • Bert Hubert
  • Bits about Money
  • Brian Krebs
  • ByteByteGo
  • Chip Huyen
  • Chips and Cheese
  • Christopher Butler
  • Colin Percival
  • Cool Infographics
  • Dan Sinker
  • David Walsh
  • Dmitry Dolzhenko
  • Dustin Curtis
  • eighty twenty
  • Elad Gil
  • Ellie Huxtable
  • Ethan Marcotte
  • Exponential View
  • FAIL Blog
  • Founder Weekly
  • Geoffrey Huntley
  • Geoffrey Litt
  • Greg Mankiw
  • Henrique Dias
  • Hypercritical
  • IEEE Spectrum
  • Investment Talk
  • Jaz
  • Jeff Geerling
  • Jonas Hietala
  • Josh Comeau
  • Lenny Rachitsky
  • Liz Danzico
  • Lou Plummer
  • Luke Wroblewski
  • Matt Baer
  • Matt Stoller
  • Matthias Endler
  • Mert Bulan
  • Mostly metrics
  • News Letter
  • NextDraft
  • Non_Interactive
  • Not Boring
  • One Useful Thing
  • Phil Eaton
  • Product Market Fit
  • Readwise
  • ReedyBear
  • Robert Heaton
  • Rohit Patel
  • Ruben Schade
  • Sage Economics
  • Sam Altman
  • Sam Rose
  • selfh.st
  • Shtetl-Optimized
  • Simon schreibt
  • Slashdot
  • Small Good Things
  • Taylor Troesh
  • Telegram Blog
  • The Macro Compass
  • The Pomp Letter
  • thesephist
  • Thinking Deep & Wide
  • Tim Kellogg
  • Understanding AI
  • 英文媒体
  • 英文推特
  • 英文独立博客
©2025 搞英语 → 看世界 | Design: Newspaperly WordPress Theme