import std;

auto main() -> int {
    std::println("Hello world!");
}

随着 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

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

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

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

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

Leave a Reply

Your email address will not be published. Required fields are marked *

You can use the Markdown in the comment form.