查看原文
其他

"Hello World" in C++23

cpluspluser CppMore 2023-04-20

随着Modules和Formatting Library顺利进入C++20,标准库Modules和Formatted output进入C++23不过是水到渠成。

这种先引入再扩展的标准发展方式在C++中已不稀奇,这两个新特性自然也就成为C++23中主要的特性之二。

C++2a之后,Ranges, Modules, Concepts, Coroutines, 以及将要引入的新特性,都将会在一定程度上改变我们以往的编译方式。

而这一切的基础,都在于新特性是否足够完善。三年一小步,六年一大步,此之谓也。



由经典的入门代码,可以看到,C++俨然成为了一门新语言。

越现代,越强大,这种使用方式以后可能会越发流行。因为不论是性能还是可用性,新特性都更具有优势。

首先是标准库Modules。

Modules具有缩短编译时间、解决重复替换、导入顺序无关,以及无需分离接口与实现等等优势,若标准库迟迟不提供Modules版本,反而会阻碍Modules的发展。

因此,标准库Modules的优先级并不低,进标准也是顺理成章。

接着是Formatted output。

用过fmt库的都清楚,这可是个好东西,或者可以说是cout终结者。

标准cout是个糟糕的设计。第一,其可用性差,基本没有格式化能力;第二,它会多次调用格式化I/O函数;第三,性能低,默认会同步标准C的流;第四,它的内容由参数交替组成,在多线程时,结果将会错乱显示;第五,它的二进制占用空间较大。

格式化输出的目标是要满足:可用性、支持Unicode编码、良好的性能,与较小的二进制占用空间。

为了不影响现有代码,该特性专门加了一个新的头文件<print>,包含两个主要函数。

#include <print>

int main() {
    const char* world = "world";
    std::print("Hello {}", world);   // doesn't print a newline
    std::println("Hello {}", world); // print a newline
}

其中std::print的格式化语法同格式化库,可以参考Using C++20 Formatting Library。而std::println则会在输出的内容之后添加一个换行,这是对比了C/Java/Rust/Go/C#/.Net等等语言之后作出的选择。

关于性能,可能看看作者的对比结果:

----------------------------------------------------------
Benchmark                Time             CPU   Iterations
----------------------------------------------------------
printf                87.0 ns         86.9 ns      7834009
ostream                255 ns          255 ns      2746434
print                 78.4 ns         78.3 ns      9095989
print_cout            89.4 ns         89.4 ns      7702973
print_cout_sync       91.5 ns         91.4 ns      7903889

可以看到,printf与print几乎要比cout快三倍,print默认会打印到stdout。当打印到cout并同步标准C的流时(print_cout_sync),print大概要快14%;当不同步标准C的流时(print_cout),依旧要快不少。

此外,使用std::print可以直接格式化输出Ranges,这可以省去大量的循环。




本文是一篇评价性的文章,并不讨论使用细节。

其实这两个新特性的内容并不算多,Modules大家可能会相对陌生,但格式化库已不是太新的东西了,平时习惯使用fmt库的对格式化输出也不会感到新奇,毕竟print在fmt库中已实现并使用了近6年。

总而言之,目前来看只要这些特性够完善,没什么大Bug,在未来将会改变一些我们一直以来养成的编程习惯,随之带来的是性能与可用性的提高,且有些现有问题将成为过去式。



您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存