在c++23中,除了有一些老的bugfix外,也增加了一些新的完善功能。这也符合标准发展的方向,除了自身的的一些小问题,还有一些需要扩展的东西也需要完善进来。就好像盖一栋大楼,下水不好,得修,但是增加一个下水反味的盖子也是不错的。这样用起来更方便,让人感觉更舒适。下面的Lambda表达式就是如此的一个例子。
在c++11推出Lambda表达式后,对c++而言,这可以说是一个非常巨大的进步,但是有一些限制还是如c++本身一样严格,比如只有没有参数才可以省略小括号,来表示这是一个函数,这真得无可厚非。但没这个小括号有一个前提,就是这个没有任何限定符,也就是说如果有限定符还是得加这个小括号,能省则省吧,在c++23中这样也合法了。
一个例子:
auto f = [](){return 0;};
//等价于:
auto f = []{return 0;};
//但是如果增加限定符,小括号不可省略
auto f = []()mutable{return 0;};
//c++23允许
auto f = []mutable{return 0;};
这个怎么说呢,就是一个完善的过程,个人觉得这不算BUG,这就是一个扩展支持罢了。
一个是#warnign指令,另外这个扩展指令有一点追求极致的感觉就是#elifdef的,但对普通开发者业说,更适应一些:
#warning "这是一个警告" //会在编译输出一个警告
#if VER > 10
#elifdef VER10
#elifndef VER11
#endif
其实就是进一步完善#elif defined和#elif !defined,这个没啥可说的。能用到这个的基本不用说明也看得清楚,用不到的,解释也没啥意义。
在c++17中已经隐式的把所有的Lambda表达式认为为了constexpr函数,让其进入了编译期进行。而在c++11原始的constexpr只能包含一条return语句,所以说,整体上看标准还是在不断的完善,向编译期进发,看来是一个方向。
c++20允许有try,同时也允许构造、析构和虚函数也可以标记为constexptr,而c++23除引入了if consteval语句来隔离运行期与编译期算法外还有几处对其进行了增强。
1、 Non-literal variables, labels, and goto statements in constexpr functions(202110L (C++23))
2、 Relaxing some constexpr restrictions (202207L (C++23))
3、 Permitting static constexpr variables in constexpr functions (202211L (C++23))
4、non-narrowing integral conversions(非窄化整形转换,就是大的转小的,比如int到char),即对bool的截断转换
5、std::size(std::array)修复即对未知指针和引用的常量表达式
6、消除了不必要的全域常量表达式的检查
简单说明一下,所谓全域检查,其实就是对constexpr在编译期一定会没问题,如果发现任何的需要在运行期执行就报错,可这东西对于编译器来说有点难度大,所以这里放开了一些口子。而数组的size主要是用来处理在指针传入NTTP(非参数类型,Non-Type Template Parameters)时的指针退化的问题。
从上面的分析可以看出,其实使用constexpr在编译处理代码一个好处是可以避免ub(undefined behaviour),这个东西其实就是标准如果没有讲清楚,或者c++编译器没有想到的就是UB,这和法律规定的情形有些类型。出现这种情况,在不同的平台,不同的OS和不同的编译器都有可能有不同的情况,有的可能正常运行,有的可能崩溃,有的可能只是达不到效果,不一而同。
更详细的在c++相关的提案和新的标准中都有说明。
估计支持C++23的编译器正在快速的推进自己的开发进度,毕竟抓住待机意味着市场的占领。不过,微软对此不是特别感冒,好多都是GNU和Clang都支持了,但MSVC还不支持。微软是不是在ALL IN那个CHATGPT啊。还是要盯紧c++2323的应用。这个应用很可能不经意就铺开了。时间不是问题,时间过得飞快。