https://blog.csdn.net/10km/article/details/80798072 在上一篇博客《c/c++:for each遍历 __VA_ARGS__ 中的每一个元素...》,我们具备了遍历__VA_ARGS__中元素的能力,那么具备这个能力有啥用呢?...当然定义结构体与枚举类似是有区别的,结构体的每个成员不光需要成员名还需要指定数据类型。所以不能简单的使用上篇文章中的FL_FOREACH宏来实现。...我们需要能遍历成对参数的能力,这就是下面的宏FL_VA_FOREACH_PAIR,这个函数宏对__VA_ARGS__(必须是偶数个)中的参数以两个一组为单位进行遍历。...发挥你的想象力,你会发现你可以顺着这个思路用macro干很多事儿。
用队列实现栈 请你仅使用两个队列实现一个后入先出(LIFO)的栈,并支持普通栈的全部四种操作(push、top、pop 和 empty)。...实现 MyStack 类: void push(int x) 将元素 x 压入栈顶。 int pop() 移除并返回栈顶元素。 int top() 返回栈顶元素。...boolean empty() 如果栈是空的,返回 true ;否则,返回 false 。...注意: 你只能使用队列的基本操作 —— 也就是 push to back、peek/pop from front、size 和 is empty 这些操作。 你所使用的语言也许不支持队列。...queue1的元素接到queue2后面 // 用这种方法使得queue1对列中的元素达到后进的反而在对首 queue2.push(queue1.front
在C++编程的探索之旅中,常量与宏定义扮演着确保程序稳定性和可维护性的关键角色。本文将深入浅出地解析这两者的核心概念、常见应用场景、易错点及其规避策略,并通过实际代码示例加深理解。...常量:不变的真理基本概念常量,顾名思义,在定义之后其值就不能再改变。C++提供了多种定义常量的方式,包括const关键字和C++11引入的constexpr。...宏定义:编译前的魔术基本概念宏定义是由预处理器在编译之前执行的文本替换操作,常用于定义常量、函数或简单的代码片段。使用场景条件编译:根据条件决定是否包含某些代码。字符串化:将标识符转换为字符串。...解决方案:使用具有唯一性的前缀。副作用:宏替换可能引起意料之外的副作用。避免策略:尽量使用内联函数替代复杂的宏定义。类型安全:宏不进行类型检查。策略:优先考虑const和constexpr。...然而,过度依赖宏定义可能会引入潜在问题,因此在现代C++编程实践中,推荐更多采用类型安全的常量定义方式。通过不断实践和反思,你将能更加熟练地驾驭这些工具,编写出更加优雅、可靠的C++代码。
本篇介绍的主要内容是关于c++ linq的,可能很多读者对c++的linq实现会比较陌生,但说到C#的linq,大家可能马上就能对应上了。...没错,c++的linq就是在c++下实现类似C# linq的机制,本身其实就是在定义一个特殊的DSL,相关的机制已经被使用在c++20的ranges库,以及不知道何时会正式推出的execution库中,...本篇我们主要围绕已进入标准的ranges实现来展开关于c++ linq的探讨,同时也将以ranges的一段代码为起点,逐步展开本篇的相关内容。...一、从ranges示例说起 ranges是c++20新增的特性,很好的弥补了c++容器和迭代器实现相对其他语言的不便性。它的使用并不复杂。...二、特殊的DSL实现 其实本质上来说, 这种实现很巧妙的利用了部分compiler time的特性,最终在c++中实现了一个从“代码->Compiler->Runtime”的一个DSL,后续我们也介绍到
this->_str; } 八·resize的实现: void string::resize(size_t n, char c) { size_t i = 0; i = _size; if...(*this == s); } 十·insert的实现: string& string::insert(size_t pos, char c) { assert(pos 的现代写法: 首先它并没有多大的提高效率,而是可以这么理解:它会让我们手动自行的操作减少一部分,通过调用如实现创造好的swap。...比如:这个自己写的swap与std里的swap 有所不同,大概就是库里用的模版出的类,会有空间反复开辟,而自己写的这个直接交换指针就好,那么就相当于指向的空间就也互换了。...=(const string& s); 返回c在string中第一次出现的位置 size_t find(char c, size_t pos = 0) const
宏扩展最大的好处有如下几点: 减少重复的代码; 完成一些通过 C 语法无法实现的功能(字符串拼接); 动态定义数据类型,实现类似 C++ 中模板的功能; 程序更容易理解、修改(例如:数字、字符串常亮)...在 C++ 中,这样的操作可以通过参数模板来实现,所谓的模板也是一种代码动态生成机制。当定义了一个函数模板后,根据调用者的实参,来动态产生多个函数。...所以,从代码的动态生成角度看,宏定义和 C++ 中的模板参数有点神似,只不过宏定义仅仅是代码扩展而已。...我记得侯杰老师在 C++ 的视屏中,利用可变参数模板这个语法,也实现了类似的功能。...其实宏对于 C 来说,就像菜刀对于厨师和歹徒一样:用的好,可以让代码结构简洁、后期维护特别方便;用的不好,就会引入晦涩的语法、难以调试的 Bug。
函数参数的默认值 C++中可以在函数声明时为参数提供一个默认值 当函数调用时没有提供参数的值,则使用默认值 参数的默认值必须在函数声明中指出 int mul(int x = 0); int main(int...x = 0; y = 1; z = 2 add(2,3); // x = 2; y = 3; z = 2 add(3,2,1); // x = 3; y = 2; z = 1 函数占位参数 在C+...(1,2); //ok 函数占位参数的意义 占位参数与默认参数结合起来使用 兼容C语言程序中可能出现的不规范写法 //下面的两种方式是否等价 void func(); void func...(void); 小结 C++ 中支持函数参数的默认值 如果函数调用时没有提供参数值,则使用默认值 参数的默认值必须从右向左提供 函数调用时使用了默认值,则后续参数必须使用默认值 C++中支持占位参数,用于兼容...C语言中的不规范写法
参考链接: C++ vsnprintf() 尽管说define有很多不足之处,很多时候我们需要使用const来替代define, 也可以使用typedef来替代define。 ...但是,在一些实际工程中,我们还是不可避免的使用到了define,这给我们带来了极大的方便。 ...1 定义头文件,防止重复包含 其实不是真正的防止重复包含头文件,而是忽略除了第一次之外的其他包含: http://blog.csdn.net/wangshubo1989/article/details...定义变量 #define WANGSHUBO_SELF_MSG WM_USER + 29 static const std::string kDate = "2016-11-25"; 3 分平台实现... 对于一些快平台开发,完全可以使用define来包含不同的文件,或是实现不同的功能: #if (MY_PLATFORM == MY_PLATFORM_WIN32) #include
_weak __attribute__((objc_gc(weak))) #define __x86_64 1 #define __x86_64__ 1 ➜ ~ clang++ -dM -E -x c+...+ /dev/null ➜ ~ clang++ -dM -E -x c++ /dev/null #define _LP64 1 #define __APPLE_CC__ 6000 #define...define __weak __attribute__((objc_gc(weak))) #define __x86_64 1 #define __x86_64__ 1 g++ -dM -E -x c+...+ /dev/null ➜ ~ g++ -dM -E -x c++ /dev/null #define _LP64 1 #define __APPLE_CC__ 6000 #define __...,避免80%的琐事。
但是,在一些实际工程中,我们还是不可避免的使用到了define,这给我们带来了极大的方便。...1 定义头文件,防止重复包含 其实不是真正的防止重复包含头文件,而是忽略除了第一次之外的其他包含: http://blog.csdn.net/wangshubo1989/article/details...2 定义变量 #define WANGSHUBO_SELF_MSG WM_USER + 29 static const std::string kDate = "2016-11-25"; 3 分平台实现...对于一些快平台开发,完全可以使用define来包含不同的文件,或是实现不同的功能: #if (MY_PLATFORM == MY_PLATFORM_WIN32) #include #...MY_PLATFORM_WIN32) #include #include #include #endif 4 定义级别 比如打日志,我们可能有很多种日志的级别
文章来自 http://www.uml.org.cn/c++/200902104.asp 在将一个C源程序转换为可执行程序的过程中, 编译预处理是最初的步骤....在有的C编译器中, 这些过程统统由一个单独的程序来完成, 编译的不同阶段实现这些不同的功能. 可以指定相应的命令选项来执行这些功能....do-while(0)语句有这广泛的应用. 2, 有的函数宏是无法用do-while(0)来实现的, 所以在调用时不能带上";", 最好在调用后添加注释说明...通过__VA_ARGS__来替换函数宏中的可变参数列表. 注意__VA_ARGS__只能用于函数宏中参数中包含有"..."的情况. e.g....printf(__VA_ARGS__) #endif tokens中的__VA_ARGS__被替换为函数宏定义中的"..."可变参数列表.
而反观 C++ 近年的进步,极少有开发流程和理念方面的改进,所谓的 Modern C++,在许多人眼里仅仅是增加了许多晦涩难懂的内容,又进一步提升了开发门槛,对其兴趣寥寥。...你可能也接触并了解过前端的组件化和响应式开发,但是否想过某一天,也能够在 C++ 实现? 概览 给出以下设计稿,试着大致评估下,多少时间可以搞定? ?...响应式编程 很多人不明白响应式实现的原理,我曾经也是,以为 C++ 作为一门静态编译型语言,是无法在运行期收集到,本应是编译期才能获知的依赖关系。毕竟没有执行到的条件分支,在运行时就根本不存在。...rgb 后缀是利用 C++ 的 User-defined literals 特性实现的自定义字面量。...只要为各平台都提供一套基本组件的 Native 实现,这个开发模式便可以进一步扩展到 Android 和 Windows,实现大部分代码跨平台复用。
C++中argmin和argmax的实现 在Python中argmin和argmax这两个函数一般是用来就一列数中的最小值和最大值的索引。C++中我们如何实现呢?...实现思路 使用STL中的std::min_element函数求出最小值; 使用STL中的std::distance计算最小值跟迭代器的头部的距离; 实现代码 #include
②这里一开始用的是string.h里的memcpy ,利用的是浅拷贝,如果让里面的类型是自定义(有资源申请已经释放的)发现浅拷贝这样会出问题,故后面改正。...,就扩大size(capacity()也要跟上);后面用value填充,如果大于就相当于截断。...; i < n; i++) { push_back(value); } } //迭代器区间初始化: //模版函数,可以用别的类型的函数...{ std::cout << *it << " "; ++it; } std::cout << std::endl; } 四·vector模拟实现过程中遇到的问题总结...这里举erase和insert的例子: 这里如果对insert插入如果没有空间开辟也可以认为迭代器失效,但是有的时候可以继续访问,但是一般建议用返回值重新赋值再使用,而开辟空间了则一定失效,必然要重新赋值
二·库内常用接口函数使用: 这里简单介绍一下除了下面要实现的接口函数还有些其他接口函数: 1·reverse(): 对于以前的vector和string,它们用的是算法库里的,故括号里还要传迭代器区间,...这里可以用 initializer_list这个模版来进行{}的初始化。..._node; } 这里需要说的也就是里面对->的重载运算符函数的实现,这样返回节点内数据的地址作用在哪?...const类型 { return _head; } 7.insert的接口函数的实现: iterator insert(iterator pos, const T& x) { //...const T& x) { insert(begin(), x); } 9·erase的接口函数的实现: 这里如果删除了就会导致迭代器失效,故要利用返回值接收再次使用。
.); 但是这种可变参数最早只能应用在真正的函数中,不能使用在宏中。...年版本的ISO C 标准中 */ #define LOG(format, ...) fprintf (stderr, format, __VA_ARGS__) ...代表一个变化的参数表 __VA_ARGS...并且可以发现printf的实现为什么一定需要%s,%d等这种格式化字符串是为了给va_*宏两点关键信息:1.可变参数的个数(百分号的个数);2.可变参数的类型(%s,%d等) 不过C++作为扩展C,当然克服了这些限制...于是C++提供了可变参数模板 C++可变参数 C++的可变参数模板是怎么做到不需要告诉参数个数的呢?...+的可变参数模板 C/C++可变参数,“## VA_ARGS”宏的介绍和使用
浅拷贝 浅拷贝:也称位拷贝,编译器只是将对象中的值拷贝过来 。...如果用std::swap交换两个string对象,将会发生1次构造和2次赋值,也就是三次深拷贝; 而string内部的swap仅仅只交换成员,代价较小。...{ //这里不需要写成友元函数,因为不需要直接访问私有成员 for (auto ch:s) { cout << ch; } return out; } //流提取 //C+...对于流提取,如果频繁的尾插,会造成频繁扩容。而且C++的扩容和C语言的扩容不一样,C++使用new不能原地扩容,只能异地扩容,异地扩容就会导致新空间的开辟、数据的拷贝、旧空间释放。...另外由于C++的标准输入流默认把空格和换行当作分隔符,不读取,所以这里要用in.get()来接收字符。 ✨getline 基本上可以直接复用流提取的代码。
list的底层是双向链表结构,双向链表中每个元素存储在互不相关的独立节点中,在节点中通过指针指向其前一个元素和后一个元素。...⭐list模拟实现 list的底层是双向链表结构,包含有一个哨兵节点。...模拟实现list,要实现下列三个类: ①list节点类 ②迭代器的类 ③list主要功能的类(size(),empty()...)...模拟实现list的类的基本功能(增删等操作)要建立在迭代器类和节点类均已实现好的情况下才得以完成。...将原生态指针进行封装,因迭代器使用形式与指针完全相同,因此在自定义的类中必须实现以下方法: 指针可以解引用,迭代器的类中必须重载operator*() 指针可以通过->访问其所指空间成员,迭代器类中必须重载
说起类型转化,我们在C语言之前的学习中可以了解到,类型转换可以分为两种情况:隐式类型转化;显示类型转化。但是为什么在c++中还要继续对类型转化做文章呢?我们一起来看: 1....所以C++出了一套类型转化的规范写法。...隐式类型转化有些情况下可能会出问题:比如数据精度丢失 显式类型转换将所有情况混合在一起,代码不够清晰 因此C++提出了自己的类型转化风格,注意因为C++要兼容C语言,所以C++中还可以使用...C++强制类型转换 static_cast,reinterpret_cast,const_cast,dynamic_cast,这是c++规范的四种类型转化。...(保持内存可见性) 就因为const_cast会导致这种危险行为的发生,所以C++就会把const_cast这个类型转化单独拿出来,但用的时候很危险!
参考链接: 通过将矩阵传递给函数的C++程序将两个矩阵相乘 任务需求:需要写一个矩阵的四则运算的小demo,通过重载运算符来实现。 ...需要实现: matrix的构造函数 动态开辟空间,实现添加矩阵。 析构函数 释放动态开辟的空间,防止内存泄露。 ...重载“+ - * /”运算符 为了方便输出 顺便实现 << 运算符 矩阵运算规则 百度到的运算规则 简单来说一下吧: 加减法 同型矩阵,对应位置相加减。 数乘 分别于矩阵中的每一位相乘。... (2) C的第行第列的元素由A的第行元素与B的第列元素对应相乘,再取乘积之和. 图说话: 难点 多维矩阵的存储 为了方便实现,采用一维数组的存储方式,将多维数组按照一定的规律存储为一维。...实现 实现类似Python中list输出的样式 想法: 递归 eg: [1,2,3,4,5,6,7,8] 为 2行4列 的数组 想要的输出为 [ [1,2,3,4],[5,6,7,8]
领取专属 10元无门槛券
手把手带您无忧上云