摘要:今天我们来讨论一个略有点绕的问题,C++ 里的内存模型和原子量。 C++98 的执行顺序问题 C++98 的年代里,开发者们已经了解了线程的概念,但** C++ 的标准里则完全没有提到线程**。从实践上,估计大家觉得不提线程,C++ 也一样能实现多线程的应用程序吧。不过,很多聪明人都忽略了,下面的事
阅读全文
摘要:为什么要使用并发编程? 在本世纪初之前,大部分开发人员不常需要关心并发编程;用到的时候,也多半只是在单处理器上执行一些后台任务而已。只有少数为昂贵的工作站或服务器进行开发的程序员,才会需要为并发性能而烦恼。原因无他,程序员们享受着摩尔定律带来的免费性能提升,而高速的 Intel 单 CPU 是性价比
阅读全文
摘要:今天我们讲一个特殊的专题,如何使用可变模板和 tuple 来完成一些常见的功能,尤其是编译期计算。 可变模板 可变模板 是 C++11 引入的一项新功能,使我们可以在模板参数里表达不定个数和类型的参数。从实际的角度,它有两个明显的用途: 用于在通用工具模板中转发参数到另外一个函数 用于在递归的模板中
阅读全文
摘要:上一讲我们初步介绍了函数对象和 lambda 表达式,今天我们来讲讲它们的主要用途——函数式编程 一个小例子 如果给定一组文件名,要求数一下文件里的总文本行数,你会怎么做? 函数的原型: 我们期待接受两个 C 字符串的迭代器,用来遍历所有的文件名;返回值代表文件中的总行数。 int count_li
阅读全文
摘要:C++98 的函数对象 函数对象(function object) 自 C++98 开始就已经被标准化了。从概念上来说,函数对象是一个可以被当作函数来用的对象。它有时也会被叫做 functor,但这个术语在范畴论里有着完全不同的含义,还是不用为妙——否则玩函数式编程的人可能会朝着你大皱眉头的。 下面
阅读全文
摘要:初识 constexpr 我们先来看一些例子: int sqr(int n) { return n * n; } int main() { int a[sqr(3)]; } 想一想,这个代码合法吗?看过之后,再想想这个代码如何? int sqr(int n) { return n * n; } in
阅读全文
摘要:模板里的一个特殊概念——替换失败非错(substitution failure is not an error),英文简称为 SFINAE。 函数模板的重载决议 我们之前已经讨论了不少模板特化。我们今天来着重看一个函数模板的情况。当一个函数名称和某个函数模板名称匹配时,重载决议过程大致如下: 根据名
阅读全文
摘要:这一讲我们来看一下模板的另外一种重要用途——编译期计算,也称作“模板元编程”。 编译期计算 首先,我们给出一个已经被证明的结论:C++ 模板是图灵完全的 这句话的意思是,使用 C++ 模板,你可以在编译期间模拟一个完整的图灵机,也就是说,可以完成任何的计算任务。 一个小例子 template <in
阅读全文
摘要:面向对象和多态 在面向对象的开发里,最基本的一个特性就是“多态” ——用相同的代码得到不同结果。以我们在[第 1 讲] 提到过的 shape 类为例,它可能会定义一些通用的功能,然后在子类里进行实现或覆盖: class shape { public: … virtual void draw(cons
阅读全文
摘要:F.20 《C++ 核心指南》的 F.20 这一条款是这么说的 : F.20: For “out” output values, prefer return values to output parameters 翻译一下: 在函数输出数值时,尽量使用返回值而非输出参数 这条可能会让一些 C++ 老
阅读全文
摘要:自定义字面量 字面量(literal)是指在源代码中写出的固定常量,它们在 C++98 里只能是原生类型,如: "hello",字符串字面量,类型是 const char[6] 1,整数字面量,类型是 int 0.0,浮点数字面量,类型是 double 3.14f,浮点数字面量,类型是 float
阅读全文
摘要:如果要挑选 C++11 带来的最重大改变的话,自动类型推断肯定排名前三。如果只看易用性或表达能力的改进的话,那它就是“舍我其谁”的第一了。 auto 自动类型推断,顾名思义,就是编译器能够根据表达式 (注意是“表达式”!!接下来会和decltype对比) 的类型,自动决定变量的类型(从 C14 开始
阅读全文
摘要:什么是迭代器? 迭代器是一个很通用的概念,并不是一个特定的类型。它实际上是一组对类型的要求([1])。它的最基本要求就是从一个端点出发,下一步、下一步地到达另一个端点。按照一般的中文习惯,也许“遍历”是比“迭代”更好的用词。我们可以遍历一个字符串的字符,遍历一个文件的内容,遍历目录里的所有文件,等等
阅读全文
摘要:函数对象及其特化 在讲容器之前,我们需要首先来讨论一下两个重要的函数对象,less 和 hash。 我们先看一下 less,小于关系。在标准库里,通用的 less 大致是这样定义的: template <class T> struct less : binary_function<T, T, boo
阅读全文
摘要:string string 一般并不被认为是一个 C++ 的容器。但鉴于其和容器有很多共同点,我们先拿 string 类来开说。 string 是模板 basic_string 对于 char 类型的特化,可以认为是一个只存放字符 char 类型数据的容器。“真正”的容器类与 string 的最大不
阅读全文
摘要:移动语义是 C11 里引入的一个重要概念;理解这个概念,是理解很多现代 C 里的优化的基础。 值分左右 我们常常会说,C++ 里有左值和右值。这话不完全对。标准里的定义实际更复杂,规定了下面这些值类别(value categories): 我们先理解一下这些名词的字面含义: 一个 lvalue 是通
阅读全文
摘要:第一步:针对单独类型的模板 为了完成智能指针首先第一步的想法。 class shape_wrapper { public: explicit shape_wrapper( shape* ptr = nullptr) : ptr_(ptr) {} ~shape_wrapper() { delete p
阅读全文
摘要:基本概念 堆,英文是 heap,在内存管理的语境下,指的是动态分配内存的区域。这个堆跟数据结构里的堆不是一回事。这里的内存,被分配之后需要手工释放,否则,就会造成内存泄漏。 C++ 标准里一个相关概念是自由存储区,英文是 free store,特指使用 new 和 delete 来分配和释放内存的区
阅读全文