C++
文章平均质量分 88
loongknown
凡是过往,皆为序章。
展开
-
Effective Modern C++ 完全解读笔记汇总
Effective Modern C++ 系列学习和解读笔记汇总。原创 2022-10-04 19:27:07 · 7299 阅读 · 1 评论 -
Item 42: Consider emplacement instead of insertion.
介绍容器empalce系列接口的优势和使用场景。原创 2022-10-01 17:56:58 · 2453 阅读 · 0 评论 -
Item 41: Consider pass by value for copyable parameters that are cheap to move and always copied.
介绍C++值传递的价值、应用场景和优势。原创 2022-10-01 16:21:01 · 1995 阅读 · 0 评论 -
C++ 按值传递的切割问题(Slicing Problem)
C++ 值传递时的切割问题原创 2022-10-01 16:01:06 · 2258 阅读 · 0 评论 -
Item 40: Use std::atomic for concurrency, volatile for special memory.
Item 40: Use std::atomic for concurrency, volatile for special memory.本 Item 探讨一下 atomic 类型和 volatile 关键字在并发程序中的区别和应用。C++11 提供了 std::atomic 类模版,可以保证操作的原子性,确保其他线程看到的肯定是操作后的结果。类似对操作加锁,而其内部使用特殊指令实现,因而开销较小。考虑下面的应用场景:std::atomic<int> ai(0); // initial原创 2022-09-24 09:03:27 · 1812 阅读 · 0 评论 -
Item 39: Consider void futures for one-shot event communication.
对于两个异步任务,经常需要一个任务(检测线程)告诉另一个任务(反应线程)特定的事件已经发生了,反应线程可以继续执行了。这个事件可能是某个数据结构被初始化了,某一阶段计算完成了,或者一个传感器数据已经采集好了。需要一种机制来完成两个任务线程间的通信,有哪些比较好的方法呢?原创 2022-09-17 22:46:01 · 2066 阅读 · 0 评论 -
C++ 多线程编程系列一:线程管理(std::thread 对象、join、detach、传参、不可拷贝性、所有权转移)
每个 C++ 程序至少有一个线程,并且是由 C++ 运行时启动的,这个线程的线程函数就是 函数。你可以在这个线程中再启动其他线程。 的构造函数申明如下:线程的启动C++ 标准库提供了 以支持多线程编程。这里先介绍通过初始化构造函数创建 对象的方式启动线程。例如: 创建了一个 对象 ,并指定了线程函数 ,随机即启动了线程。 会阻塞到线程函数执行完成。线程任务可以是任意的可调用类型(callable type)。可调用类型包括:例如,可调用类型为仿函数时:但是,这个时候需要注意下面启动线程的方式原创 2022-08-27 09:14:19 · 3362 阅读 · 0 评论 -
C++‘s most vexing parse
这段代码很简单,在主线程(main函数)中起动一个子线程,并等待子线程执行完成。,参数为一个函数指针(返回值类型为 task,无函数名,参数为空)。第二个申明中行参省去指针类型也是合法的,第三个申明中行参直接省去了函数名也是合法的。第二个申明,对行参加上圆括号,编译器会认为是冗余的并忽略。第三个省略了行参名。再看本文开头给出的例子,就不难理解编译报错的原因了。对象并启动该线程执行,而是申明了一个函数,该函数的返回值类型为。根本就不是一个类类型的对象,而是一个函数,这里的。至此,本文结束,希望对你有所帮助。原创 2022-08-20 09:27:55 · 3404 阅读 · 0 评论 -
Item 38: Be aware of varying thread handle destructor behavior.
那么这个结果就需要被拷贝多次,不是所有结果的类型都是可以拷贝的。其实 callee 的结果是被存储在独立于 caller 和 callee 之外的特殊位置,被成为共享状态(shared state)的位置。直观地观察,被调用者(callee)和调用者(caller)之间有一个通信通道(channel),callee 异步执行完成后,将结果写入(通常通过。再者,callee 的结果也不能存储在 caller 的。方法之前,callee 可能已经结束了,callee 的局部变量。一个 joinable 的。原创 2022-08-20 08:40:45 · 1831 阅读 · 0 评论 -
编译时编程(Compile-Time Programming)
C++ 有很多方式可以实现编译时计算,而模板为编译时计算提供了更多的可能。constexpr本文将介绍这些特性。原创 2022-08-13 10:04:05 · 2020 阅读 · 0 评论 -
Item 37: Make std::threads unjoinable on all paths.
每个 只会处于两种状态状态之一:其一为 ,其二为 。一个 的 对应于一个正在或可能在运行的底层线程。例如,一个对应于处于阻塞或者等待调度的底层线程的 是 。对应于底层线程的 已经执行完成也可以被认为是 。而 的线程包括: 的 状态之所以重要的原因之一是:一个 状态的 对象的析构函数的调用会导致正在运行程序停止运行。例如,我们有一个 函数,它接收一个过滤函数 和一个最大值 作为参数。 检查并确定所有条件满足时,对 0 到 执行 。对于这样的场景,一般会选择基于任务的方式来实现,原创 2022-08-06 15:33:59 · 2197 阅读 · 1 评论 -
Item 36: Specify std::launch::async if asynchronicity is essential.
中讨论的标准库的线程管理模块承担了线程的创建和释放的职责,可以有效避免超额订阅、保证负载均衡。要访问本地线程存储(TLS,ThreadLocalStorage)时,无法预测访问的是哪个线程的本地存储。执行一个函数或可调用对象时,你通常期望这个函数是异步执行。综上,如果你的使用场景不是以下几种,则需要考虑是否需要替换。,以上代码就会有问题。,以上代码没有问题。但是,如果执行策略为。是根据执行策略决定是否会异步执行。可能是同步执行也可能是异步执行。是并发执行,也即执行策略为。有两种执行策略,定义在。...原创 2022-07-30 19:41:32 · 2132 阅读 · 0 评论 -
值传递还是引用传递(By Value or By Reference)
对于模板实参,选择值传递还是引用传递时一个复杂的问题。虽然通常情况下引用传递的代价更低,但是我们还是建议在没有更好的原因的话,建议使用值传递。下面就值传递和引用传递做一些探讨。...原创 2022-07-30 12:11:40 · 2334 阅读 · 0 评论 -
移动语义(Move Semantics)与 enable_if<>
移动语义(MoveSemantics)无疑是C++11最重要的特性,可以用于优化拷贝和赋值操作。本章将讨论下移动语义对模板设计的影响。原创 2022-07-17 21:34:06 · 2142 阅读 · 3 评论 -
Item 35: Prefer task-based programming to thread-based.
如果你想异步运行一个函数 ,你有两个基本的选择:基于线程的方法(thread-based)和基于任务的方法(task-based)。在比较二者优劣前,我们先介绍下 C++ 软件中线程的3个层次:基于任务的方法一般要优于基于线程的方法。 有返回值,可以代表任务的执行状态。基于线程的方法没有提供一个很好的机制获取返回值。而 返回的 对象提供了 方法可以获取到返回值。并且当 返回异常时,基于线程的方法直接抛出 ,而基于任务的方法可以根据返回值做异常处理。系统的软件线程是有限的,当请求创建的 多于系统提原创 2022-07-10 10:52:33 · 2035 阅读 · 1 评论 -
Tricky Basics of C++ Templates
这章将介绍关于模板的一些看起来有点棘手或者诡异的知识点,比如 的其他用途、零初始化、函数模板的字符串字面值参数等等。这些知识点在你常年的模板实践中总会遇到。在模板内部,可以使用关键字 指明一个标识符为一个类型。例如:使用 告诉编译器 是类内定义的一个类型。没有关键字 前缀的话,编译器会将 当作一个没有类型的数据成员,而 会被认为是一个乘法表达式。对于作用域内的内置类型(int,double,pointer,etc.),没有显示进行初始化赋值时,将会产生一个未定义的值。对于模板,如果模板类型原创 2022-07-03 16:51:22 · 2367 阅读 · 0 评论 -
可变参数模板 Variadic Templates
从 C++11 开始,模板可以有任意个模板参数,也即所谓的可变参数模板。定义一个函数 如下,用于接收不同类型的不同参数。 被称为模板参数包(template parameter pack), 被称为函数参数包(function parameter pack)。模板函数 首先打印第一个参数,然后递归调用自己打印剩余参数。为了结束递归,需要提供一个非模板类型重载函数,用于处理最后的空参数包。为了更直观地感受可变参数模板地递归处理过程,可以在以上 中插入 ,打印出函数的调用。当发生 调用时,输出如下:原创 2022-06-26 23:21:27 · 2600 阅读 · 0 评论 -
非类型模板参数 Nontype Template Parameters
除了类型可以作为模板参数,普通值也可以作为模板函数,即非类型模板参数(Nontype Template Parameters)。前一章使用的例子 使用的是标准库中的容器管理元素,也可以使用固定大小的 ,它的优势是内存管理开销更小,数组的大小可以交给用户指定。使用该模板需要同时指定类型和个数。 用于指定 的大小。非类型模板参数也可以有默认值。非类型函数模板参数也可以为函数定义非类型模板参数。也可以指定一个模板参数,由该参数之前的参数推断出其类型。或者保证传值的类型和指定的类型相同。非类型模板原创 2022-06-19 23:26:12 · 3466 阅读 · 0 评论 -
类模板 Class Templates
本系列是对 C++ Templates The Complete Guide Second Edition 的学习和解读。本文介绍类模板。原创 2022-06-18 09:36:01 · 4306 阅读 · 1 评论 -
C++ 强制类型转换:static_cast、dynamic_cast、const_cast 和 reinterpret_cast
C++ 强制类型转换:static_cast、dynamic_cast、const_cast 和 reinterpret_cast原创 2022-06-18 08:48:49 · 8357 阅读 · 5 评论 -
函数模板 Function Templates
从本文开始,对 [C++ Templates The Complete Guide Second Edition](http://www.tmplbook.com) 进行系统学习和解读。本文介绍函数模板。原创 2022-06-11 12:40:47 · 2404 阅读 · 0 评论 -
Item 34: Prefer lambdas to std::bind.
Effective Modern C++ Item 34 的学习和解读。原创 2022-06-05 14:28:17 · 2405 阅读 · 1 评论 -
Item 33: Use decltype on auto&& parameters to std::forward them.
Effective Modern C++ Item 33 的学习和解读。通用 lambda 完美转发的实现。原创 2022-06-03 22:52:36 · 1865 阅读 · 1 评论 -
Item 32: Use init capture to move objects into closures.
Effective Modern C++ Item 3 初始化捕获模式的学习和解读。原创 2022-06-03 13:32:52 · 1683 阅读 · 0 评论 -
Item 31: Avoid default capture modes.
Item 31: Avoid default capture modes.Effective Modern C++ Item 31 的学习和解读。C++11 lambda 表达式有两种默认捕获模式:传引用捕获和传值捕获。默认传引用捕获可能导致引用悬挂的问题。默认传值捕获其实也不能避免这个问题,并且你的 lambda 闭包也不是独立的。先看默认传引用捕获导致引用悬挂的问题。看下面的代码片段:using FilterContainer = std::vector<std::function<原创 2022-05-29 23:45:11 · 2305 阅读 · 0 评论 -
Item 30: Familiarize yourself with perfect forwarding failure cases.
Item 30: Familiarize yourself with perfect forwarding failure cases.花括号初始化(统一初始化、列表初始化)0 或 NULL 作为空指针仅仅声明整型的静态常量(static const)数据成员函数重载和函数模板位域Effective Modern C++ Item 30 的学习和解读。完美转发(perfect forwarding)是 C++11 非常重要的一个特性。转发意味着一个函数将其参数传给另一函数,第二个函数的目的是接收第一个函原创 2022-05-15 23:35:36 · 2083 阅读 · 1 评论 -
Item 29: Assume that move operations are not present, not cheap, and not used.
Item 29: Assume that move operations are not present, not cheap, and not used.Effective Modern C++ Item 29 的学习和解读。在 C++11 新增特性中,移动语义无疑是最重要的一个,它允许编译器使用高效的 move 操作代替低效的 copy 操作。一般地,把你的 C++98 代码使用 C++11 编译器重新编译后,运行的会更快一些。然而,凡是都不是绝对的,本 item 会介绍一些移动语义不可用、不那么原创 2022-05-04 21:53:56 · 2335 阅读 · 0 评论 -
Item 28: Understand reference collapsing.
Item 28: Understand reference collapsing.引用折叠规则万能引用的实例化std::forward 机制生成 auto 变量typedef 类型别名decltype类型推导Effective Modern C++ Item 28 的学习和解读。引用折叠规则所谓引用折叠(reference collapsing)就是当引用指向引用(reference to reference)会折叠(或者坍塌)成一种引用。我们知道,引用分为左值引用和右值引用,因此,引用指向引用就存在原创 2022-04-30 20:45:50 · 2013 阅读 · 0 评论 -
Item 27: Familiarize yourself with alternatives to overloading on universal references.
Item 27: Familiarize yourself with alternatives to overloading on universal references.放弃重载const T& 传递值传递使用 Tag 分发约束接受通用引用的模板权衡Effective Modern C++ Item 27 的学习和解读。在 Item26 中建议大家尽量不要对万能引用进行重载,但同时也确实存在需要对万能引用进行重载的场景。今天就和大家探索下如何满足这种场景的需求,这个 Item 将沿用上个 I原创 2022-04-17 15:25:11 · 2818 阅读 · 1 评论 -
C++ 设计模式之单例模式
C++设计模式之单例模式饿汉模式懒汉模式Meyers 单例模式单例模式:类只有一个实例,并且全局可访问。单例模式又分为饿汉模式和懒汉模式。饿汉模式饿汉模式是指类在加载时候就创建单例的对象。// singleton.h#ifndef __SINGLETON_H__#define __SINGLETON_H__ class Singleton { public: static Singleton* getInstance() { return原创 2022-04-16 11:08:04 · 3697 阅读 · 2 评论 -
Item 26: Avoid overloading on universal references.
Item 26: Avoid overloading on universal references.Effective Modern C++ Item 26 的学习和解读。这一节给出的建议是尽量不要对万能引用参数的函数进行重载,根因是重载函数的匹配规则。先从一个例子说起:std::multiset<std::string> names; // global data structurevoid logAndAdd(const std::string& name){ au原创 2022-04-05 11:11:57 · 2469 阅读 · 0 评论 -
Item 25: Use std::move on rvalue references, std::forward on universal references.
Item 25: Use std::move on rvalue references, std::forward on universal references.Effective Modern C++ Item 25 的学习和解读。如果函数参数为右值引用,那么这个参数只能绑定到一个右值,你应该充分利用右值的特性(可以移动),使用 std::move 无条件将参数转换为右值。class Widget {public: Widget(Widget&& rhs) //原创 2022-04-04 00:12:20 · 2272 阅读 · 0 评论 -
C++ 返回值优化 RVO
C++ 返回值优化 RVO引子返回值优化 RVORVO 限制参考在调试 C++ 拷贝和移动系列构造函数时候,发现构造函数调用和预期不太一样,经过查阅相关资料,发现是返回值优化(RVO)从中做梗。了解了事实真相后,今天就和大家聊聊这个 RVO。引子直接看一个例子:#include <iostream>class A {public: A (){ std::cout << "A(): addr= " << this << st原创 2022-04-04 05:46:31 · 5986 阅读 · 4 评论 -
Item 24: Distinguish universal references from rvalue references.
Item 24: Distinguish universal references from rvalue references.Effective Modern C++ Item 24 的学习和解读。在 C++11 移动语义出现后,遇到 T&& ,你可能认为就是右值引用,其实不然,这可能是一个万能引用(universal reference),右值引用和万能引用只是形式上相似而已,二者实际上是两个概念。右值引用只能绑定到一个右值上;而万能引用既可以绑定到一个右值,也可以绑定到一个左值。原创 2022-03-27 15:25:58 · 2361 阅读 · 0 评论 -
Item 23: Understand std::move and std::forward.
Item 23: Understand std::move and std::forward.Effective Modern C++ Item 23 的学习和解读。std::move 和 std::forward 并不像他们名字所表达的那样,实际上 std::move 并没有移动数据,std::forward 也并没有转发数据,并且它们在运行期什么也没做。先说 std::move,我们看下它在 C++11 中简易的实现:template<typename T> // in nam原创 2022-03-27 00:09:09 · 2690 阅读 · 0 评论 -
Item 22: When using the Pimpl Idiom, define special member functions in the implementation file.
Item 22: When using the Pimpl Idiom, define special member functions in the implementation file.PImpl 技术(编译防火墙)PImpl 技术的智能指针版本Effective Modern C++ Item 22 的学习和解读。这部分介绍一个智能指针的应用场景:编译防火墙。PImpl 技术(编译防火墙)PImpl(Pointer to implementation)是一种 C++ 惯用技术,它是通过将类的原创 2022-03-26 07:34:53 · 2647 阅读 · 1 评论 -
Item 21: Prefer std::make_unique and std::make_shared to direct use of new.
Item 21: Prefer std::make_unique and std::make_shared to direct use of new.make 函数的优点支持 auto避免异常效率更高make 函数的缺陷无法自定义 deleter语义歧义延长对象销毁时间一个 trickstd::make_shared 是 C++11 开始支持的,但是 std::make_unique 是 C++14 才开始支持。如果你的编译器只支持 C++11,你可以实现自己的 make_unique。template原创 2022-03-20 23:31:30 · 2239 阅读 · 0 评论 -
Item 20: Use std::weak_ptr for std::shared_ptr like pointers that can dangle.
Item 20: Use std::weak_ptr for std::shared_ptr like pointers that can dangle.std::weak_ptr 的特点std::weak_ptr 的典型应用循环引用带缓存的工厂方法std::weak_ptr 的特点std::weak_ptr 通常不会单独使用,一般是与 std::shared_ptr 搭配使用,可以将 std::weak_ptr 类型指针视为 std::shared_ptr 指针的一种辅助工具,借用 std::weak原创 2022-03-20 15:04:37 · 2014 阅读 · 0 评论 -
Item 19: Use std::shared_ptr for shared-ownership resource management.
Item 19: Use std::shared_ptr for shared-ownership resource management.引用计数自定义deleter控制块Effective Modern C++ Item 19 的学习和解读。上文中介绍了 std::unique_ptr ,它对指向的资源拥有独占所有权。本文介绍一种新的智能指针:std::shared_ptr,它和其他指向该资源的指针有共享所有权,它可以拷贝和传递,并且通过引用计数来管理资源的生命周期。std::shared_pt原创 2022-03-19 22:28:48 · 2738 阅读 · 0 评论 -
Item 18: Use std::unique_ptr for exclusive-ownership resource management.
Item 18: Use std::unique_ptr for exclusive-ownership resource management.独占所有权占用内存的大小一个典型应用杂项Effective Modern C++ Item 18 的学习和解读。原始指针非常灵活,但是使用陷阱多,容易出错,智能指针则更容易使用。本文介绍的智能指针是 std::unique_ptr。独占所有权std::unique_ptr 表现出独占所有权的语义。一个非空的 std::unique_ptr 总是对它指向的资原创 2022-03-13 21:31:42 · 2820 阅读 · 0 评论