![](https://img-blog.csdnimg.cn/20201014180756930.png?x-oss-process=image/resize,m_fixed,h_64,w_64)
C++笔记
Erick_Lv
菜鸡互啄
展开
-
C++ .template 关键字
template 关键字除了用于作为模板声明之外,还有一个作用,显式说明模板成员函数,这一点类似于typename 显式说明成员类型。给出代码实例:#include <iostream>template<typename T, size_t N>class Collection {public: template<size_t I> void setValue(T &&t) { data[I] = t; }原创 2021-01-06 23:32:06 · 2061 阅读 · 1 评论 -
SFINAE 应用1
简介Substitution Failed Is Not An Error,之前笔记介绍过。这里介绍一个拓展的应用,foo 函数传入可调用对象和对应的参数,之后会判定是否可以传入对应的参数,并返回函数的执行结果,具体参考代码。这是 SFINAE 一个经典应用#include <iostream>#include <type_traits>#include <utility>#include <string>// 获取 Fn 调用 Args 的结果原创 2021-01-05 13:37:33 · 207 阅读 · 0 评论 -
std::nullptr_t & std::void_t
std::nullptr_tstd::nullptr_t是nullptr的模板类型,用法如下:#include <iostream>#include <type_traits>void foo(int *) { std::cout << "int*\n";}void foo(double *) { std::cout << "double*\n";}void foo(std::nullptr_t) { std::c原创 2021-01-04 22:52:54 · 594 阅读 · 0 评论 -
RTTI & decltype & declval
ri# RTTIRun-Time Type Information,运行时类型信息。RTTI这种情况,一般是运行时的类型转换的,一般是和类型转换配合使用,给出代码实例:#include <iostream>class Base {public: virtual void foo() { std::cout << "base derived\n"; }};class Derived: public Base {public:原创 2021-01-01 14:22:24 · 267 阅读 · 0 评论 -
SNIFE 和 std::enable_if
类型基础在回顾模板之前,需要明确一个概念:模板编程是针对类型的计算。。这和我们平时的代码不同,我们平时写的程序都是针对数据的。在模板元编程中,typename 用于定义类型;using 用于给模板类型赋值,注意这里的赋值和变量的赋值意义不同。参考下面的代码:#include <iostream>using LL = long long;struct Foo { using T1 = int; using T2 = float;};int main() {原创 2020-12-31 01:09:34 · 646 阅读 · 0 评论 -
C++字节存储方式和reinterpret_cast
数据存储方式和数据类型变量变量可以认为是一个内存块,该内存块中存放了变量的二进制表示格式。其实,汇编语言中,没有变量类型的概念,而在C等静态高级语言中,都有变量类型的概念。1字节 = 1B = 8bit = 2^8 => 0-256所以ASCII标准字符有256个,sizeof(int) = 4,因此int最大是2(8×4−1)2^{(8 \times 4 - 1)}2(8×4−1),-1是因为有符号位可以这么理解,变量类型只是程序员告诉编译器变量的表示方式;而最终的汇编形式,仍然是没有数据原创 2020-10-27 13:51:30 · 768 阅读 · 0 评论 -
std::any
std::any可以认为,这是C语言void*的高阶版本,直接给出代码实例:#include <iostream>#include <any>#include <variant>#include <type_traits>#include <vector>struct Op1 {};struct Op2 {};void test(const std::vector<Op1>&) { std::cou原创 2020-08-17 14:16:18 · 289 阅读 · 0 评论 -
boost context上下文切换
上下文简介首先要理解boost::context的概念和应用场景。程序在执行的时候,当前的执行的代码环境和所处的状态,就是context。boost::context保留了当前程序执行时的寄存器等的状态,可以认为是一个上下文A;然后线程就可以去执行其他的代码,完成执行后,可以切回上下文A,并从当初切走的地方执行,而且当初的上下文的现场不变,这就是完成了一次真正意义上的上下文切换。上线文切换,在协程和用户态线程等有重要的意义(统称它们为routine),我们可以启动一定数量的操作系统的线程,然后让rout原创 2020-07-19 20:57:32 · 3785 阅读 · 1 评论 -
C++重载->和*运算符
->和*也可以用于重载,不过这种模式不太常见。最经典的例子是智能指针。直接给出一个简版的unique_ptr的代码示例,说明这两者的重载模式:#include <iostream>template <typename T>class UniquePointer {public: UniquePointer(T* val = nullptr) { m_val = val; } ~UniquePointer() { // 退出时原创 2020-07-14 00:17:14 · 720 阅读 · 0 评论 -
C++类型萃取 -- 1
std::enable_if_t#include <iostream>#include <type_traits>#include <string>template<typename T, typename = std::enable_if_t<(sizeof(T) > 2)>>void foo(const T&& val) { std::cout << val <<原创 2020-07-07 17:07:51 · 232 阅读 · 0 评论 -
C++ 可变索引模板 和 template template
代码实例:#include <iostream>#include <deque>template <typename T>class MyContainer {public: void push(T&& arg) { m_que.emplace_back(std::forward<T>(arg)); } T pop() { auto&& v = m_que.fr原创 2020-07-03 19:18:02 · 309 阅读 · 0 评论 -
C++模板元编程---折叠表达式
折叠表达式同样是运行在编译期间的,先给出基本的规则:注意,一元表达式只有&&、||或者,有缺省值,三者空包的默认值分别是:true、false和void()所有支持的运算符是:+ - * / % ^ & | = < > << >> += -= *= /= %= ^= &= |= <<= >>= == != <= >= && || , .* ->*给出一元折叠代码示例:#原创 2020-06-27 18:54:11 · 469 阅读 · 0 评论 -
C++模板元 -- 变长参数模板
变长参数模板边长参数模板的一般格式是:// 编译递归的终止位置template <T arg>void foo(T arg) { // do something with arg}// 展开编译表达式template <typename T, typename ...Args>void foo(T arg, Args... args) { foo(arg, args...);}给出代码示例,注意都是编译器展开的代码模板,而非运行期。#include原创 2020-06-27 18:26:25 · 692 阅读 · 0 评论 -
理解C++ Executor的设计理念
文章目录简介代码示例参考简介很多时候,我们的可调用对象需要某些非参数依赖的执行环境。可以这么理解,我们的任务是就绪的,不需要依赖外界传入参数了,只需要以某种方式控制方法的when 、where和how即可。三个分别是指:where:可调用对象的执行位置,比如可以在内部或者外部的处理器(线程)上执行,并从内部或者外部的处理器(线程)上获取结果when:可调用对象的执行时间,比如立刻执行或者被调度执行how:可调用对象的执行方式,比如在CPU或者GPU上执行,可以矢量化计算等举个例子:int原创 2020-06-25 19:59:55 · 4844 阅读 · 1 评论 -
C++智能指针的“GC”
C++的智能指针使用了引用计数来自动释放内存,因此释放内存并检查的过程,可以视为“GC”,比如有大量智能指针的节点,一次性reset指针的时候,可能会有卡顿,给出一个例子,创建50w个节点,观测GC的耗时:#include <iostream>#include <memory>#include <chrono>struct LinkNode { ...原创 2020-01-10 02:22:49 · 674 阅读 · 0 评论 -
C++ typename的使用方式
基本用法对于泛型模板的声明,typename和class的作用一样,都是为了说明模板类型。template &lt;typename T, class C&gt;void fun(T t, C c); // 这里的T和C是等价的与class的区别https://stackoverflow.com/questions/2023977/difference-of-keywords-typ...原创 2018-12-24 19:56:15 · 823 阅读 · 0 评论 -
C++11线程库模板
推荐一个非常好的C++11的线程库模板:https://github.com/progschj/ThreadPool/blob/master/ThreadPool.h包含了C++11的特性,重点学习阻塞方式,而且该库的实现方式非常巧妙,代码行数也很少。...原创 2018-12-24 14:00:03 · 328 阅读 · 0 评论 -
C++直接修改std::set元素的方法
简介元素在std::set中构造后,如果需要查找,则调用find成员函数,但是该方式有一个致命的缺陷,就是返回的是一个常指针,无法通过指针更改元素的值。这样做也是有意义的,因为如果是int之类的元素,本身相当于键值,更改键值就破坏了原来红黑树的结构了。但是,有些情况下,我们自定义了一些数据结构,但是需要更改结构的非键值部分,此时不想拿出再插入。更特别的情况是元素的不可构造和不可移动的,此时就需要...原创 2018-12-28 20:54:12 · 10391 阅读 · 4 评论 -
多线程lambda数据捕获
lambda函数的执行是在真正调用的时候,这和普通函数没有太大区别,只是lambda没有实际的名称而已。lambda的另一个特点是可以捕获周围的变量,捕获的方式分为值和引用。捕获的是立刻发生的,而不是等到函数调用的时候,只要声明一个lambda而且声明了捕获,那么捕获的动作就会发生。但是注意,如果是传递引用,那么得到的结果是不确定的,因为引用只是原来变量的一个别名,这也是非常危险的行为。在多线...原创 2018-12-27 23:04:05 · 925 阅读 · 0 评论 -
C++的reinterpret_cast
该关键字的作用是把任意的指针类型转换到指定的数据类型。注意转换的参数是指针,但是不推荐使用。有一种方式比较适合,就是哈希函数的情况:#include &lt;iostream&gt;unsigned short Hash(void* p) { unsigned int val = reinterpret_cast&lt;unsigned int&gt;(p); return ...原创 2019-01-04 15:06:32 · 1056 阅读 · 0 评论 -
C/C++函数的本质以及多线程函数的调用过程
C/C++中,函数的本质是一段可执行代码,代码包括了局部变量、全局变量的地址等等。到汇编语言的级别,变量函数等都可以视为汇编的代码片段。函数的本质就是一个可执行代码片段的集合线程的详细介绍:http://www.cnblogs.com/tracylee/archive/2012/10/29/2744228.html一个线程有自己的空间,有自己的局部变量。当一个线程执行一个函数的时候,会复制函数...原创 2018-12-27 17:54:07 · 3315 阅读 · 1 评论 -
C++传入任意的函数类型作为参数
C++编程中,有些时候需要传入函数作为参数,这在STL中作为谓词经常用到。传入的可以是函数、函数对象和lambda表达式。编程的时候,把它当成一个模板类型传入即可。以下给出一个简单的例子:#include &lt;iostream&gt;#include &lt;utility&gt;#include &lt;functional&gt;template&lt;typename F&am原创 2018-12-16 22:54:28 · 6551 阅读 · 0 评论 -
C++变长参数模板
先给出一个例子:#include &lt;iostream&gt;#include &lt;cstdlib&gt;void print() { // 这里结束模板递归地终止链 std::cout &lt;&lt; "I am empty function and I am called at last.\n";}template&lt;t原创 2018-12-15 23:47:15 · 1215 阅读 · 0 评论 -
C语言格式化字节流
简介在Linux套接字编程中,发送的都是void类型的数据,本质上可以看成字节流,因为我们一般是发送的char的数据。那么,这样就涉及到一个问题,如果我们的数据不是字符串,而是整型、浮点型和更加复杂的结构体,那么此时就需要对这些结构进行格式化。一般通过snprintf把数据写入到指定的流中,这个函数比sprinitf更安全,因为增加了最大缓冲区的限制。然后通过sscanf读取数据。只要保证数据...原创 2019-02-09 13:53:43 · 1669 阅读 · 0 评论 -
C++11多线程的原子操作
原子操作是同时只能有一个线程执行一个操作,不用使用互斥量即可实现,但是速度慢,而且一般只支持原生的类型,不够灵活。更多的用处是作为信号量进行使用。示例代码,以int为例子:#include <atomic>#include <thread>#include <iostream>#include <cstdlib>#include <...原创 2018-12-15 15:59:44 · 455 阅读 · 0 评论 -
C++虚函数与虚表
虚函数虚析构函数虚表机制原创 2019-01-17 15:06:07 · 191 阅读 · 0 评论 -
C++模板参数的总结
文章主要参考官方文档:https://en.cppreference.com/w/cpp/language/template_parametersType template parameter这是最基本的模板类型,也是最常用的:template <typename T>T foo(T t) {/*......*/}template <class T = void>...原创 2019-01-13 19:51:33 · 2467 阅读 · 0 评论 -
Effective Modern C++ 第四章,C++智能指针
智能指针 Smart Pointer一些说明:C++98中有智能指针std::auto_ptr,在C++11中,出现std::unique_ptr。std::unique_ptr包含了std::auto_ptr所有的功能;除此之外,后者效率更高,而且不会改变复制对象的意义。因此,只要编译器没有限制,我们应该使用std::unique_ptr而不是std::auto_ptr。正如它的名字...原创 2018-03-01 16:08:12 · 325 阅读 · 0 评论 -
C++回调函数作为通信机制
回调函数特别适合实现类之间的通信. 类之间的通信, 不同的平台有各自的解决方案, 比如windows有MFC, 这里面就包含大量的回调函数机制, 保证类之间的通信. 这里, 实现一个自定义的回调函数机制, 进行基础的通信.问题背景:有一个服务器的类, 服务器有一系列的客户端的集合. 是否断开与服务器的连接由客户端决定. 如果客户端申请断开连接, 那么服务器就要把需要断开链接的客户端从集合中进行...原创 2019-05-18 17:05:17 · 2355 阅读 · 2 评论 -
C++的占位符std::placeholder
笔记参考自官方文档: https://en.cppreference.com/w/cpp/utility/functional/placeholders简单一句话概括, 一个变量的占位符, 用于函数绑定时使用, 具体直接参考代码:#include <functional>#include <string>#include <iostream>voi...原创 2019-05-12 22:00:00 · 6357 阅读 · 0 评论 -
C++11多线程之 std::packaged_task
简介先给出官网的一个地址:http://www.cplusplus.com/reference/future/packaged_task/?kw=packaged_task个人认为,相当于一个装饰器,封装了一系列的函数,然后启动一个线程进行异步执行,而且函数的类型是高度可定制化的。启动线程的时候,仅需要把封装的任何和对应的参数依次传入即可。std::packaged_task返回一个std::...原创 2019-03-14 19:16:39 · 329 阅读 · 0 评论 -
现代C++模板元编程基础
元函数的基础介绍C++的模板元编程是函数式编程,所以函数是一等公民。一切在编译期间执行的函数都可以称为元函数。元函数有struct和constexpr两种定义方式,前者是一直使用的,后者是C++11以及以后版本的关键字。constexpr字面意思是常量表达式,因此表达式内部不允许出现运行期可以改变的量。在元函数中,一切都是可计算的,也就是说,数值和数据类型都是可以计算的量。这和运行期的函数存在...原创 2019-01-17 00:08:46 · 706 阅读 · 0 评论 -
C++14实现一个线程池
简介该线程池是基于C++14标准的,可以完成添加任务,暂停执行,继续执行等的工作。所有的可被线程池调度的任务,必须继承Object类,并且实现process()函数;同时,必须指定一个Policy类,用于线程池的优先级调度策略。具体思路利用C++14的条件变量完成,借助优先级队列,实现任务的优先级调度。最基本的策略模式,策略由用户指定。传入的Object类及其子类,Policy类及其子类必须...原创 2019-01-31 22:55:48 · 395 阅读 · 0 评论 -
C++奇特的递归模板式
奇特的递归模板式(CRTP, Cruiously Recurring Template Pattern),该方式奇特之处在于:派生类会把自己本身作为模板参数传递给基类。基本结构如下:template <typename D>class Base {/*...*/};class Derived: public Base<Derived> {/*...*/};这里...原创 2019-01-19 11:20:31 · 622 阅读 · 0 评论 -
模板元实现顺序、分支和循环结构
顺序顺序执行没有太多可说的,唯一需要注意的是,类型的声明必须按照顺序,否则编译器无法识别。不按照顺序的声明,在运行时的程序是合法的,编译过程会扫描两次,第一次是找声明位置,第二次是具体的转换。分支使用std::conditional和std::conditional_t处理#include &amp;amp;amp;lt;iostream&amp;amp;amp;gt;#include &amp;amp;amp;lt;type_traits&原创 2019-01-19 09:53:03 · 648 阅读 · 0 评论 -
C++域作用符及其高级用法
基础用法命名空间说明符最常用的,,std::cout之类的,或者是自定义的命名空间。类作用符这是第二个基础的用法,用于类函数定义使用的class C {public: void foo();};void C::foo() {/*...*/}全局变量说明符当局部变量和全局变量重名的时候,使用::来显式说明全局变量。#include <iostream>s...原创 2019-01-13 20:39:48 · 1396 阅读 · 1 评论 -
C++11多线程------std::async
std::async可以认为是封装了一个std::promise,该函数返回一个std::future,用于获取其他线程的数据。一般有两种模式:std::lanch::async:最常用的异步模式,每次都要执行一遍std::lanch::defer:只在第一次调用的时候执行,之后再调用返回之前的调用结果。给出代码示例:#include &amp;lt;iostream&amp;gt;#includ...原创 2018-12-15 14:10:39 · 621 阅读 · 0 评论 -
C++11多线程---互斥量、锁、条件变量的总结
关于互斥量std::mutex的总结互斥量用于组成代码的临界区。C++的多线程模型是基于内存的,或者说是基于代码片段的,这和我们操作系统学习的临界区概念基本一致,但是与Golang不同,Golang是基于消息模型的。一个std::mutex的lock()和unlock()之间的代码片段组成一个临界区,这个临界区内部同时最多只能有一个线程进行访问,可以理解为这个片段内部的代码是受到保护的,不会被...原创 2018-12-15 01:07:48 · 1662 阅读 · 0 评论 -
C++读取字符串中的数字的方法
代码实例:#include <iostream>#include <sstream>#include <fstream>using namespace std;int main(){ string str("55.5818061829 119.6388702393 22.33"); double t; istringstre...原创 2018-12-04 21:50:32 · 21082 阅读 · 1 评论 -
C++面向对象机制
基类和派生类基类中使用virtual声明函数,显示的说明这是可以进行重载的。子类中在函数的最后添加上override关键字显示的说明重载基类的函数,这是可选的。但是,如果不声明为虚函数,则解析发生在编译时,而不是运行时。这样会导致在声明为基类的引用或者指针时,只能调用基类的函数,即使此处使用了派生类,也无法进行运行时检验!virtual只需要在基类中声明一次即可,这样整个继承链中的子类都可以不...原创 2018-09-20 09:53:43 · 889 阅读 · 0 评论