网易首页 > 网易号 > 正文 申请入驻

C++ 之父 2024 年末重磅演讲 | 重新认识 C++:跨世纪的现代演进

0
分享至

作者 | 《新程序员》编辑部

出品 | CSDN(ID:CSDNnews)

12 月 5 日,美国国家工程院、ACM、IEEE 院士、C++ 之父 Bjarne Stroustrup 在「」上发表了题为《重新认识 C++:跨世纪的现代演进》的演讲。屏幕上,演示文稿的第一页就令人印象深刻:“C++ 几乎可以实现我们所期望的一切!

从构建操作系统到开发高性能游戏引擎,从支持人工智能框架到驱动航天器控制系统,C++ 一直是系统级软件开发的首选语言。然而,这位编程语言大师并不是在炫耀 C++ 的强大,而是要指出一个关键问题:“正因为它如此强大,我们更要谨慎选择正确的使用方式。就像 goto 语句——它无所不能,所以我们几乎从来不用它。同样的,虽然用 20 世纪 80 年代的方式写 C++ 也能完成任务,但这显然不是最佳选择。我们需要明确自己的真正需求,避免重蹈覆辙。”

Stroustrup 指出了一个常见的认知误区:人们往往把“熟悉”等同于“简单”。对很多开发者来说,见过千百遍的代码写法看起来简单,而新的特性和方法则显得复杂。

“我们必须努力避免这种思维定式,否则就会永远停留在 20 世纪。”他强调道,“今天,我想谈谈我所认为的当代 C++、现代 C++ 的基础是什么。我认为,当代的编程方式能让代码变得更简单、更安全、更高效,远胜于任何旧版本的 C++。(在这一语境下,“当代”往往指的是 C++20/23/26 等当前的版本)”

欢迎回顾:

当代 C++ 的简洁之美为了说明当代 C++的优势,Stroustrup 首先以他收到的一个来自《龙书》(Dragon Book,编译器设计领域的经典教材)作者、AWK 语言的创造者之一 Alfred V. Aho 的难题为例。这个例子展示了如何用 C++ 简洁地处理文本中的不重复行:

import std;
using namespace std;

int main() // 输出输入流中的不重复行
{
    unordered_map

  m; // 哈希表 for (string line; getline(cin,line); ) if (m[line]++ == 0) cout << line << '\n'; } 

“这段代码展示了几个重要特点,”Stroustrup 解释道,“首先,完全没有使用预处理器;其次,代码高效且容易理解;第三,如果需要进一步优化,也完全可以做到——但关键是,在开始优化之前,这段代码本身就已经相当高效了。”

“让我们试试另一种处理不重复行的方式。”他进一步提出,“为什么要一直输出行呢?也许我想要的是一个仅仅收集输入中不重复行的程序。”

这样一个简单函数就能轻松实现:

vector

  collect_lines(istream& is) // 从输入中获取不重复行 { unordered_set

 m; // 哈希表 for (string line; getline(is,line); ) m.insert(line); return vector(m.begin(),m.end()); } auto lines = collect_lines(cin); 


“C++ 的类型系统会自动推导出我们需要的是 string 的 vector,”Stroustrup 解释说,“而且返回时不需要复制,直接移动就行了。这样的实现既简洁又高效。”

“但这里的 vector 构造有点啰嗦。我希望 vector 能直接接受这个集合本身,”Stroustrup 说,“所以我写了一个函数,它可以接受任何范围并从中创建 vector。”于是他展示了一个更简洁的版本:

vector

 collect_lines(istream& is) // 从输入中获取不重复行 { unordered_set

 m; // 哈希表 for (string line; getline(is,line); ) m.insert(line); return make_vector(m); } auto lines = collect_lines(cin); 


“标准库不需要提供所有功能。有时候自己写个简单函数就能解决问题,比如这个 make_vector。”他最终总结道,“也许在 C++ 的未来版本中,vector 会直接支持这种构造方式,那时这个函数就不需要了。”

“从这些例子可以看出我最重视的一点:思想的直接表达。”Stroustrup 紧接着列出了他重视的每一项事物:

谈到 C++ 的发展历程,Stroustrup 指出:“一些关键特性和技术已有多年历史,比如带构造函数和析构函数的类、异常处理机制、模板、std::vector……等等。另一些则是较新的发展,如 constexpr 函数和 consteval 函数、lambda 表达式、模块、概念、std::shared_ptr……等等。关键在于将这些特性作为一个整体来运用。

“不要盲目使用所有新特性,也不要局限于仅使用新特性,”他强调道,“如果想了解最新特性和未来发展方向的更多细节,可以参考相关的技术讨论视频。我更关注的是如何将语言作为一个整体来开发好的软件。因为最终编程语言的价值体现在其应用程序的质量之中。

资源管理:C++ 的基石

我们知道,相比归还东西,人们更倾向于获取东西,”Stroustrup 首先打了个生动的比方,“问任何一个图书管理员就知道了,人们借书后常常忘记还书。在大型软件中,如果我们必须显式地返还借用的资源,我们肯定会遗漏一些。”

Stroustrup 将资源定义为“任何必须获取并在之后释放(归还)的对象”。“这包括内存、string(字符串)、互斥锁、文件句柄、套接字、线程句柄、着色器等等很多东西,”他解释道。“从这个词的含义来看,在编程中我们要处理的很多东西都是资源。”

在 C++ 中,每个资源(resource)都应该有对应的句柄(handle)来管理它的生存期。句柄负责资源的访问和释放,这种机制是通过对生存期的严格控制来实现的。

为了解决这个问题,Stroustrup 提出了几个关键原则:

1.避免手动释放资源——不要在应用程序代码中出现 free()、delete 等资源释放操作;

2.使用资源句柄——每个对象都由负责访问和释放的句柄管理;

3.基于作用域管理——所有资源句柄都属于特定作用域,可以在作用域间转移;

他用一段简单但富有启发性的代码来说明这些原则:

template

 class Vector { // T 类型元素的 vector public: Vector(initializer_list ); // 构造函数:分配内存并初始化元素 ~Vector(); // 析构函数:销毁元素并释放内存 // ... private: T* elem; // 指向元素的指针 int sz; // 元素数量 }; void fct() { Vector

 constants {1, 1.618, 3.14, 2.99e8}; Vector

 designers {"Strachey", "Richards", "Ritchie"}; // ... Vector string ,jthread>> vp { {"producer",prod}, {"consumer",cons}}; } 



“这就是C++ 的基石:构造函数(constructor)和析构函数(destructor),”Stroustrup 说道,“如果需要获取任何资源,那是构造函数的工作;如果需要归还资源,那是析构函数的工作。这里我们将抽象层次从机器级的指针和大小提升到了更高的层次。我们把它包装成一个类型,这个类型行为正确,有赋值操作,有访问函数,并且能正确清理。”

他特别指出了资源管理机制的递归性:“string 拥有一些字符,这里的 pair 拥有一个 string 和一个 jthread。jthread 拥有对操作系统线程的引用。这些都是递归进行的。神奇之处在于最后的闭合花括号——那里是所有东西都被隐式而可靠地清理的地方。”

为了做好资源管理,Stroustrup 强调了对生存期的控制:

  • 构造:首次使用前建立对象的不变量(如果有的话);

  • 析构:最后使用后释放所有资源(如果有的话);

  • 拷贝:a = b 意味着 a == b,且它们是独立的对象;

  • 移动:在作用域间转移资源所有权;

“这些机制让我们能够开发出更安全、更可靠的代码,”他总结道,“因为资源管理不再依赖于程序员的记忆力,而是由语言机制自动保证。

错误处理的策略

“在确保资源安全的基础上,我们还需要有明确的错误处理(error handling)策略,”Stroustrup 随即转入了另一个重要话题。他指出,C++ 中有两种主要的错误处理方式,它们各有适用场景:

“对于那些常见且可在局部处理的失败情况,使用错误码(error code)是合适的,这种方式避免了使用效率低下且丑陋的try-catch结构。”他解释了第一种情况,“但问题是,我们经常忘记检查错误码,这可能导致错误的结果继续传播。而且,这种方式不适用于构造函数和运算符。比如说,当你写 Matrix x = y + z 这样的表达式时,就没有地方放置错误返回语句和测试。”

“另一方面,对于那些罕见且无法在局部处理的错误,异常处理(exception handling)是更好的选择。”Stroustrup 继续说道,“错误可以沿调用链向上传播,避免陷入 ‘错误码地狱’。未捕获的异常会导致程序终止,而不是产生错误结果。重要的是,这种机制必须与RAII(资源获取即初始化)配合使用,依赖作用域资源句柄。”

他用一个具体的例子说明了这个观点:

void fct(jthread& prod, string name)
{
ifstream in { name };
if (!in) { /* ... */ } // 预期可能发生错误

vector

 constants {1, 1.618, 3.14, 2.99e8}; // 内存可能耗尽 vector

 designers {"Strachey", "Richards", "Ritchie"}; // 嵌套构造 jthread cons { receiver }; pair

 pipeline[] { {"producer", prod}, {"consumer", cons}}; // ... } 



“想象一下,如果只使用单一的错误处理方式,这段代码会变得多么复杂,”Stroustrup 说,“每个操作都可能失败:文件打开可能失败,内存分配可能失败,构造过程可能失败。使用异常处理,我们可以集中处理这些错误,而不是在每个可能的失败点都编写检查代码。

Stroustrup 还提到了一个最新的研究发现:“即便对小型系统,异常处理也可能比错误码更高效。我们最近看到一个很好的演示,展示了在小型固件中使用 C++ 异常可以产生更小、更快的代码。”

“关键是要记住,”他强调,“错误处理不是要选择唯一正确的方式,而是要根据具体情况选择最合适的方式。有时是错误码,有时是异常,重要的是要有一个明确的策略。即便对小型系统,异常处理机制也可能比错误码更高效。Khalil Estell 最近在 CppCon 2024 上的演示*展示了在小型固件中使用 C++ 异常可以产生更小、更快的代码。”

* Khalil 的演讲内容:https://www.youtube.com/watch?v=bY2FlayomlE

模块:打破“包含”的魔咒

谈到代码组织,Stroustrup 首先指出了一个困扰 C++ 开发者多年的问题:“头文件包含的顺序依赖问题一直是个麻烦。#include "a.h" 后跟 #include "b.h",可能与顺序颠倒后的结果完全不同。这种基于文本的包含机制会导致:包含具有传递性、相同的代码被重复编译多次、容易引发宏定义冲突等问题。”

相比之下,C++20 引入的模块(modules)机制则完全不同:

import a;
import b;

“这与顺序无关,”Stroustrup 解释道,“写成下面这样,效果完全一样。”

import b;
import a;

“import 不具有传递性,模块化的代码更加干净,而且能显著提升编译速度——这不是百分比级的提升,而是数量级的提升。

紧接着,他兴奋地宣布:“经过几十年,我们终于在 C++ 中实现了模块。我们不必再使用 include 了!这是我长期计划的一部分——逐步淘汰 C 预处理器。预处理器会给工具带来麻烦,因为工具看到的和程序员看到的是不一样的。”

他分享了来自一家德国嵌入式系统公司的实际案例。该公司有一个传统的设备信息库 libgalil,通过头文件包含机制,最终会展开成约 50 万行代码(其中 15 万行是空行)。即便以现代编译器的速度,处理这样的代码也需要 1.5 秒。然而,当他们将其改造为模块后,预处理后只有 5 行代码,编译仅用了 62 毫秒,实现了 25 倍的速度提升。

“当然,你不能期待在所有情况下都能获得 25 倍的提升,”Stroustrup 说,“但根据经验,使用具名模块通常能让编译速度提高 7-10 倍。这就是促使人们将代码从旧风格改造为新风格的动力。虽然这个过程并不容易——毕竟我们有数十亿行现存的代码——但这种改进确实显著。”

在标准库方面,C++23 已经提供了模块化支持。最重要的是模块 std,它包含了完整的 std 命名空间:

import std; // 包含整个标准库

“这带来了惊人的改进,”Stroustrup 说,“以十分之一的时间提供十倍的信息——效率提升了 100 倍。这意味着我不用像以前那样等待编译时喝那么多咖啡了。

他特别推荐观看 Danielle Eckert 在 2022 年 CppCon 上题为《Contemporary C++ in Action》的演讲,“这个演讲展示了现代 C++ 特性在实际项目中的应用,非常精彩。如果可能,你一定要去看一下这个视频。”

视频链接:https://www.youtube.com/watch?v=yUIFdL3D0Vk

“模块化的概念早在 1994 年的《C++ 语言的设计和演化》中就已提出,”Stroustrup 补充道,“现在我们终于实现了!这个特性不仅让代码更清晰,也大大提升了开发效率。”

泛型编程与概念

泛型编程(generic programming)是当代 C++ 的关键基础,”Stroustrup 如此介绍道,“这个想法最早可以追溯到 80 年代初。那时我就描述过这个概念,只是当时我以为可以用宏来实现——关于这点我错了,但对需要泛型编程这一点我是对的。现代 C++ 中的大量泛型编程思想都来自 Alex Stepanov。”

泛型编程为 C++ 带来了多方面的优势:代码更加简洁、思想表达更直观、实现零开销抽象、保证类型安全。它在标准库中无处不在:容器和算法、并发、内存管理、I/O、string 和正则表达式等。

Stroustrup 用一个简单的例子说明了基于概念的泛型编程:

void sort(Sortable_range auto& r);

vector

 vs; // ... 填充 vs ... sort(vs); array

 ai; // ... 填充 ai ... sort(ai); list

 lsti; // ... 填充 lsti ... sort(lsti); // 编译错误:list 不支持随机访问 



“这段代码展示了几个隐含的要求,”他解释道,“容器的类型、元素的类型、元素的数量、比较准则等。概念(concept)的作用就是明确指定对类型 r 的要求。当编译器看到 vector 时,它会问:‘这个 vector 有支持随机访问的元素序列吗? ’ 是的,有。 ‘这些元素是可以比较的吗?’ 是的。所以代码可以工作。但对于 list,因为它不支持随机访问,编译器会立即发现这个错误。”

Stroustrup 特别指出,“概念不等同于 ‘类型的类型’。概念是可以作用于多个类型的谓词。有些概念还可以接受值参数,可以混合类型和值。但概念本质上是函数,而不是像其他语言中那样仅仅是函数签名的集合。”

随后,他进一步解释了为什么 list 不支持随机访问是一个特意的设计:“如果在一个包含 50 万个元素的 list 中使用下标访问,会非常非常慢。所以这种限制实际上是在保护开发者避免写出性能糟糕的代码。

更复杂的情况是,许多算法都需要多个模板参数类型,而且这些类型之间往往需要建立某种关系。Stroustrup 展示了一个来自标准库的例子:

template
indirect_unary_predicate

 Pred> Iterator_t ranges::find_if(R&& r, Pred p); vector

  numbers;  // 存储数字的 string,如 "13" 和 "123.45" // ... 填充 numbers ... auto q = find_if(numbers,     [](const string& s) { return stoi(s) < 42; });  // lambda 表达式 


“这里的概念实际上是编译期谓词(compile-time predicate),它们在编译期执行并返回布尔值。通常一个概念会基于其他概念构建,形成一个完整的类型约束体系。”

Stroustrup 表示,概念并不是什么新鲜事物:“每个成功的泛型库都包含某种形式的概念。它们存在于设计者的构思中,记录于技术文档中,体现在代码注释中。比如 C/C++ 的内置类型概念(算术类型和浮点类型)、STL 中的迭代器、序列和容器概念、数学概念(单子、群、环、域)、图论概念(边、顶点、图、有向无环图等)……”

讲到此处,Stroustrup 致敬了 C 语言之父丹尼斯·里奇(Dennis Ritchie, 1941-2011):

“实际上,我们只是为这些概念提供了语言层面的表示方法,让编译器能够理解和检查它们。这要求我们学会有效运用这种语言支持。”他说道,“编译期编程(compile-time programming)在当今的 C++ 中非常基础,这种技术也已经存在很长时间了。有趣的是,在 2010 年时,还有人断言编译时求值不仅毫无用处,而且根本无法实现。现在的发展已经证明,他们的判断完全错了。”

“使用概念还带来了许多实际好处:支持更好的程序设计,提升代码可读性和可维护性,避免过度使用无约束的 auto 和 typename,大幅改进错误信息。”他打了个比方:“还记得那个只有内置类型没有类(class)的年代吗?C++ 从未有过这种时期,但现在的 C 语言仍是这样。好在 C 现在也有了函数原型。”

“概念的引入还极大地简化了条件约束的表达。”Stroustrup 展示了一个例子:

template

 class Ptr { // ... T* operator->() requires is_class ; // 仅当 T 是类时才提供 -> 运算符 }; template

 class Pair { // ... template TT, convertible UU> Pair(const TT&, const UU&); // 只为可转换为成员的类型提供构造函数 }; 


传统的 enable_if 方案原始、丑陋、非通用,且容易出错,”他最终评价道,“而使用概念,我们可以用更简洁、更直观的方式表达这些约束。

协程:状态保持!

“说到协程(coroutine),这其实是个有趣的故事,”Stroustrup 回忆道,“在 C++ 发展的最初十年,协程是我们的一个重要优势。但后来一些公司因为它不适合他们的机器架构而反对,结果我们失去了这个特性。现在,我们终于把它找回来了。

协程的特点是能在多次调用之间保持其状态。Stroustrup 用一个生成斐波那契数列的例子来说明:

generator

 fibonacci() // 生成 0,1,1,2,3,5,8,13 ... { int a = 0; // 初始值 int b = 1; while (true) { int next = a + b; co_yield a; // 返回当前斐波那契数 a = b; // 更新状态 b = next; } } for (auto v: fibonacci()) cout << v << '\n'; 

“这里的妙处在于状态的保持,”他解释道,“我们有计算的状态——a、b 和 next——它就这样不断地计算下一个斐波那契数。协程已经被嵌入到迭代器系统中,所以我们可以用简单的 for 循环来获取数列中的值。”

但这个例子还有一个小问题:“这是个无限序列,显然会带来问题,我们会遇到溢出。那么如何限制它只生成特定数量的值呢?”Stroustrup 展示了改进的版本:

template

 generator

 fibonacci() // 生成前 N 个斐波那契数 { int a = 0; int b = 1; int count = 0; while (count < N) { int next = a + b; co_yield a; a = b; b = next; count++; } } for (auto v: fibonacci<10>()) // 只生成十个数:0,1,1,2,3,5,8,13,21,34 cout << v << '\n'; 


“虽然标准库对协程的支持还不如我想要的那么完善,”Stroustrup 说,“但这个例子中使用的 generator 已经在 C++23 中可用了。如果你使用的是较早的编译器,还可以使用 Facebook 的 coro 库或其他任务库。这个例子很好地展示了模板和协程是如何和谐地协同工作的。”

“协程为我们提供了一种漂亮的方式来处理需要保持状态的计算,”他总结道。“它让代码更容易理解,也更容易维护。这正是我们一直追求的目标:简单的事情简单做。

调优:“洋葱原则”

“对某些代码来说,调优是必要的,”Stroustrup 转入了性能优化的话题。“但我们都听过 ‘避免过早优化’ 这个建议。重要的是要在优化前后都进行性能测量,同时在设计接口时就要考虑优化空间。”

他提出了几个关键原则:

1. 接口设计需明确定义

2. 保持类型信息的完整性

3. 提供足够信息支持检查和优化

4. 管理复杂度:"简单的事情简单做!"

“我把这个叫做 ‘洋葱原则’,”Stroustrup 打了个生动的比方,“你可以把代码想象成洋葱的层。每当我们需要优化或处理特殊情况,我们就可能需要剥掉一层抽象。但要记住,每剥掉一层,你就会哭得更厉害。”

“为什么会这样?”他继续解释道,“因为每深入一层,你就有可能遇到更多的错误,必须写更多的代码,代码也更难理解。所以在真正需要之前,不要轻易剥掉一层抽象。这就是我对 ‘不要过早优化’ 的理解。”

此外,关于并发(concurrency),Stroustrup 指出这是一个需要单独讨论的重要话题。“你需要它来提高效率。在标准库中有广泛的、相当低层的并发支持:线程和锁、共享机制、并行算法、协作取消、Future 机制、协程等等。这些都是为了性能,但同时也带来了复杂性。”

指南和规格配置:走向未来

不要停留在 20 世纪,”演讲走进尾声时,Stroustrup 直截了当地说,“但这说起来容易做起来难。大多数代码都包含一些旧的部分,升级这些代码既困难又耗时。虽然升级能带来巨大好处——比如引入模块能显著提升编译速度——但要摒弃次优技术确实很难,因为我们不仅要面对海量的历史代码,还要克服根深蒂固的编程习惯。”

我们面临一个根本性的问题,我们不能改变语言本身——稳定性和兼容性是 C++ 的核心优势。但我们可以改变使用语言的方式。

为了说明这一点,Stroustrup 分享了一个有趣的观察:“大约每两周,我都会收到一个有趣的请求。这个请求总是包含三个部分:首先是跟我说 ‘C++ 太复杂了,必须简化’——我同意,确实如此——但紧接着又跟我说 ‘顺便提一下,我们绝对需要增加这两个新特性’。而且还要保证 ‘别破坏我的代码,我可是有上百万行呢’。这三件事是没法同时做到的。

“正是基于这种现实,”他继续说,“我们采取了一种务实的策略:通过一套灵活的指南规则体系来简化语言的使用,而不是改变语言本身。这些指南可以根据项目需求选择性采纳。比如 C++ Core Guidelines 就是一个很好的例子,而且已经有了实践工具的支持,如 Visual Studio、GCC 和 Clang-Tidy 都能帮助执行这些指南——这不是科幻小说,这些工具现在就可以使用。”

在标准委员会中,Stroustrup 和同事们正在推进一个更进一步的方案:规格配置(profile)。“每个规格配置是一套强制性的指南规则,”他解释道,“虽然现在还在制定中,但其目标很明确:让开发者能够根据需要选择不同类型的安全性级别和执行强度。这将帮助我们在保持语言强大的同时,使其更容易正确使用。”

Stroustrup 建议的初始规格配置包括:

1.算法:全面的范围检查,禁止解引用 end() 迭代器;

2.算术:检测上溢和下溢;

3.类型转换:全部禁用;

4.并发:消除死锁和数据竞争(这是个难点);

5.初始化:所有对象必须初始化;

6.失效:禁止通过已失效的指针访问(包括悬空指针);

7.指针:禁止对内置指针使用下标操作(应使用 span、vector、string 等);

8.范围:捕获范围错误;

9.RAII:所有资源必须由句柄管理;

10.类型:涵盖初始化、范围、转换、失效和指针规则;

11.联合体:禁止使用 union(应使用 variant 等);

他说:“我们需要那些底层的、复杂的、接近硬件的、容易出错的、专家级的特性,因为它们是高效实现高层功能的基础。很多底层特性在正确使用时都很有价值。但一旦我们有了这些基础,就可以在此之上建立更安全、更简单的编程模型。”

我们想要的是「增强版 C++」——简单、安全、灵活、高效,而不是功能受限的子集。我们不能失去 C++ 最重要的特性:高性能和对硬件的直接控制。而且这些改进不会改变语言的本质,最终的代码仍然是符合 ISO C++ 标准的。”

Stroustrup 还总结了 C++ 的编程模型:

  • 静态类型系统,同时支持内置类型和用户定义类型

  • 支持值语义和引用语义

  • 统一的资源管理机制(RAII)

  • 高效的面向对象编程

  • 灵活且高效的泛型编程

  • 编译期编程

  • 直接访问硬件和操作系统

  • 通过库实现的并发支持(借助内部指令)

  • 最终淘汰 C 预处理器

在演讲的最后,Stroustrup 展示了一张 C++ 用户数量增长的图表。

“C++ 在设计之初就考虑到语言会不断演进,”他说,“从 1979 年的 C with Classes,到 1998 年引入异常、模板和命名空间,再到 2011 年增加并发、lambda 表达式和智能指针,直到 2020 年带来概念、协程、模块等特性,C++ 一直在成长。”

“我从一开始就知道,我不可能独自在合理的时间内构建出我想要的完整语言,”他坦言道。“所以 C++ 在不断演进,现在有了很多真正有用的新特性。但关键是,我们要活在曲线的上方,使用当代 C++ 中可用的工具,而不是停留在最古老的部分。因为归根到底——编程语言的价值体现在其应用程序的质量之中。

在 C++ 之父 Bjarne Stroustrup 的主题演讲《重新认识 C++:跨世纪的现代演进》中,他系统地探讨了资源管理、错误处理、模块化、泛型编程等 C++ 的核心特性,并详细阐述了他对 C++ 未来发展的愿景。而在同场的炉边谈话环节中,Bjarne Stroustrup 不仅分享了对当前 C++ 发展现状的思考,也表达了对未来的期待。

想要第一时间深入了解 C++ 之父的观点,或重温他对 C++ 技术演进的精彩论述?为了帮助开发者更好地理解和运用现代 C++,CSDN 联合 Boolan 特别策划了“C++ 名家系列直播活动”。全球顶尖的 C++ 专家,将为参与者深入解析现代 C++ 的核心理念和实践经验。更重要的是,我们还将向参与者独家赠送《现代 C++ 白皮书》中文版。这份白皮书凝聚了 C++ 之父 Stroustrup 15 年来的技术思考,以及全球 C++ 专家群体的智慧结晶,堪称现代 C++ 开发者的必读指南。

扫描文末二维码,即可预约参与直播并领取白皮书。让我们一起探索现代 C++ 的技术深度,把握编程语言演进的前沿方向。

特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。

Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.

相关推荐
热点推荐
韩媒:韩国冰联轻率处罚导致林孝埈换国籍 曾有女队友大胆为他作证

韩媒:韩国冰联轻率处罚导致林孝埈换国籍 曾有女队友大胆为他作证

劲爆体坛
2026-02-20 09:26:02
斯诺克比赛结果:6-3晋级4强,赵心童大满贯出局

斯诺克比赛结果:6-3晋级4强,赵心童大满贯出局

墨史轩
2026-02-20 06:22:06
第一集就要打码,这部新剧太生猛了

第一集就要打码,这部新剧太生猛了

来看美剧
2026-02-20 21:32:52
断供来了,斯洛伐克真扛不住了,接下来咋办?

断供来了,斯洛伐克真扛不住了,接下来咋办?

奇思妙想生活家
2026-02-20 06:04:47
林徽因落选的国徽方案,网友看后感叹:审美确实一绝,但真不合适

林徽因落选的国徽方案,网友看后感叹:审美确实一绝,但真不合适

抽象派大师
2026-01-03 02:13:54
贝克汉姆坚持儿子离婚,16亿婚前协议导致和解困难

贝克汉姆坚持儿子离婚,16亿婚前协议导致和解困难

君笙的拂兮
2026-01-26 15:51:34
剑桥科技(06166.HK)尾盘跌超6% 股价创上市新低

剑桥科技(06166.HK)尾盘跌超6% 股价创上市新低

每日经济新闻
2026-02-20 15:54:08
德媒:德国总理的北京之行非常的棘手,德国不能接受中国主导

德媒:德国总理的北京之行非常的棘手,德国不能接受中国主导

我心纵横天地间
2026-02-20 21:43:22
他是"乒乓神童",关键时刻狠心拒绝国外优厚待遇,执意只为回中国

他是"乒乓神童",关键时刻狠心拒绝国外优厚待遇,执意只为回中国

以茶带书
2026-02-20 23:41:44
国行 iPhone,开启 AI 设置界面!

国行 iPhone,开启 AI 设置界面!

花果科技
2026-02-19 22:00:48
春节档破35亿!《飞驰人生3》领跑,《镖人》逆袭至单日票房第2

春节档破35亿!《飞驰人生3》领跑,《镖人》逆袭至单日票房第2

露珠聊影视
2026-02-20 20:48:55
特朗普回应奥巴马涉外星人言论:我不知道是否真实存在,但奥巴马肯定泄密了

特朗普回应奥巴马涉外星人言论:我不知道是否真实存在,但奥巴马肯定泄密了

环球网资讯
2026-02-20 09:26:07
年初二,53岁董卿回江苏亲戚家吃饭,穿3千元马甲,皮肤白气质好

年初二,53岁董卿回江苏亲戚家吃饭,穿3千元马甲,皮肤白气质好

天天热点见闻
2026-02-19 06:31:51
纽约市长不但免费之说食言,还要加税

纽约市长不但免费之说食言,还要加税

移光幻影
2026-02-20 20:55:17
盐城“415大案”主犯,到底有多残忍?审判后旁听群众:应判凌迟

盐城“415大案”主犯,到底有多残忍?审判后旁听群众:应判凌迟

谈史论天地
2026-02-03 06:05:28
法国专家:中国电力已经让世界畏惧!为何中国人自己却浑然不知?

法国专家:中国电力已经让世界畏惧!为何中国人自己却浑然不知?

行者聊官
2026-01-23 09:26:28
42岁霍启山和“妲己”娜然携手出游,家族默认儿媳,细节太戳人

42岁霍启山和“妲己”娜然携手出游,家族默认儿媳,细节太戳人

独步天涯
2026-02-20 15:42:10
调兵遣将一个月后,美军转过头一看,一支中国海军舰队现身阿曼湾

调兵遣将一个月后,美军转过头一看,一支中国海军舰队现身阿曼湾

锋芒点兵
2026-02-16 10:25:31
中国终止越南核电站合作,十年投入成泡影,日本计划落空

中国终止越南核电站合作,十年投入成泡影,日本计划落空

聚焦真实瞬间
2026-01-21 08:04:16
看了观众对陈丽君电影首秀的评价,何赛飞的话,终于有人信了!

看了观众对陈丽君电影首秀的评价,何赛飞的话,终于有人信了!

听风喃
2026-02-20 19:08:34
2026-02-21 01:40:49
CSDN incentive-icons
CSDN
成就一亿技术人
26330文章数 242232关注度
往期回顾 全部

科技要闻

莫迪举手欢呼 两大AI掌门人却握拳尴尬对峙

头条要闻

贝加尔湖遇难者遗体已被发现 涉事司机系私下接单

头条要闻

贝加尔湖遇难者遗体已被发现 涉事司机系私下接单

体育要闻

金牌夫妻!王心迪徐梦桃赛后拥抱太甜了

娱乐要闻

《将门独后》开拍,王鹤棣孟子义主演

财经要闻

特朗普全球关税被推翻!有何影响?

汽车要闻

比亚迪的“颜值担当”来了 方程豹首款轿车路跑信息曝光

态度原创

数码
教育
家居
游戏
军事航空

数码要闻

AMD "Zen 6" MSDT主流桌面处理器被曝最快2027年推出

教育要闻

出炉,2026考研初试成绩查询!

家居要闻

本真栖居 爱暖伴流年

宝可梦红/绿售价20美元!任天堂表示我们觉得很有趣

军事要闻

消息人士透露:美军赴黄海活动 解放军有效应对处置

无障碍浏览 进入关怀版