C++ 挖坑与填坑
文章平均质量分 60
C++语法总结、常用以及不常用知识点总结、相关书籍网课的笔记
拾牙慧者
会点c++、python;
展开
-
C++简单实现布隆过滤器
布隆过滤器是一种空间效率高、适用于大规模数据集的概率性数据结构。它可以帮助快速判断一个元素是否可能存在于一个集合中,以及可能不存在于集合中(有一定的误判率)。原创 2023-12-18 23:43:00 · 293 阅读 · 0 评论 -
CMPXCHG和lwarx (LL)/stwcx (SC)
如果不使用循环来重试 CAS 操作,那么在竞争激烈的情况下,单次 CAS 操作失败后,程序可能就会放弃修改,这样会导致并发操作的数据一致性出现问题。通过在循环中重试 CAS 操作,可以确保在 CAS 操作成功之前不会跳出循环,从而保证了原子性和一致性。一种常见的方法是创建一个结构体,其中包含指向数据的指针以及版本号或标记,并使用原子操作来更新和比较这两个值。总之,即使使用了原子操作函数,也仍然需要搭配使用循环,以确保 CAS 操作的成功和数据的一致性。当CAS操作失败时,可以检查版本戳并采取适当的行动。原创 2023-12-18 23:41:51 · 266 阅读 · 0 评论 -
【C++】RVO、NRVO优化以及返回值优化失效的场景
但结论是明显的,移动语义可以解决编译器无法解决的优化问题,因而总是有用的。对于下面这样的代码,一旦打开g++/clang++的RVO/NRVO,从ReturnValue函数中a变量拷贝/移动构造临时变量,以及从临时变量拷贝/移动构造b的二重奏就通通没有了。需要注意的是,无论RVO是否生效,代码的行为应始终符合C++语言中对拷贝构造函数、析构函数和移动构造函数的要求。返回值优化(Return Value Optimization,RVO)是一种编译器优化技术,旨在减少函数返回对象的副本构造和析构成本。原创 2023-12-14 23:58:16 · 505 阅读 · 0 评论 -
【C++】实现一个数组均分函数
后,移动并不会改变原始向量的大小。相反,它只是将元素的所有权从一个容器转移到另一个容器,这意味着在移动后原始向量变为空(或者说内部元素被置空),但其大小并不会随之改变。在这之前我们有了解过make_move_iterator的使用方式,可以帮我们免去拷贝。的结果仍然会显示为原始向量的初始大小,而不是 0,尽管元素已经被移走并且值为空。如果你想要获取移动后的新向量。来获取新向量的元素个数。在你的代码中,当你使用。所以,在你的情况下,原创 2023-12-14 23:52:13 · 219 阅读 · 0 评论 -
【C++】简化for-range的算法函数
这段代码使用了lambda表达式作为std::transform函数的第四个参数,用于将mat_set中的所有ComplexMat对象存储到res向量中。用于对一个序列中的每个元素进行转换,并将结果存储到另一个序列中。用于检查容器中的所有元素是否都满足条件。用于检查是否有任何元素满足给定条件。用于统计满足条件的元素个数。原创 2023-12-14 23:49:44 · 199 阅读 · 0 评论 -
如何使用std::function 和std::bind取代继承
这样做可以减少代码的复杂性,提高代码的可读性和可重用性。然而,在某些情况下,继承仍然是合适的选择,特别是当需要建立明确的关系和多态行为时,继承仍然是强大且有用的工具。来实现多态行为、模块化代码、代码重用和面向接口编程的情况。通过利用函数指针和绑定器,我们可以灵活地组合和调用不同的函数或函数对象,而无需依赖继承关系。继承是面向对象编程中一种重要的机制,但有时候使用继承可能会导致代码变得复杂、难以理解和不易维护。可以在某些情况下替代继承,这是因为它们提供了一种更灵活和可重用的方法来实现代码的动态行为。原创 2023-12-13 23:58:04 · 220 阅读 · 0 评论 -
boost::any 与 boost::any_cast
提供了一种灵活的方式来存储和检索任意类型的值,并且可以在运行时进行类型转换。它对于需要动态类型操作的情况非常有用,但需要小心使用以避免潜在的类型转换错误。可以在运行时存储和检索不同类型的值,同时保持类型安全和内存管理的正确性。这使得我们可以在不事先知道具体类型的情况下,以一种通用的方式处理各种类型的值。请注意,在实际使用时,确保对于不同类型的值有适当的处理方法,例如设置默认值、抛出异常等,以满足您的需求。用于处理类型安全的任意类型值的存储和检索。中存储的字符串,实际上是以C风格的字符串(原创 2023-09-05 00:19:43 · 474 阅读 · 0 评论 -
常见的可以提升编码效率的 modern C++ 语法糖【1】
在上面的示例中,我们首先定义了一个std::string类型的字符串str,然后使用std::string_view类型的view1和view2表示字符串的一部分或整个字符串。需要注意的是,std::string_view类型只是字符串的一个视图,不拥有字符串的内存,因此需要确保原始字符串的生命周期大于或等于std::string_view类型的生命周期。std::string_view是C++17标准中引入的一种轻量级字符串视图类型,可以用于表示字符串的一部分或整个字符串,而不需要进行内存分配或拷贝。原创 2023-08-27 15:19:38 · 357 阅读 · 0 评论 -
enable_shared_from_this
shared_from_this()不能在构造函数里调用,因为在构造对象的时候,它还没有被交给shared_ptr接管。它提供了一种机制,使类能够安全地从成员函数内部获得指向自身的。是一个基类模板,用于解决在类成员函数中获取类对象的。下面是一个示例代码,展示了。原创 2023-08-27 15:08:01 · 1800 阅读 · 1 评论 -
weak_ptr是怎么探知对象生死的
是C++智能指针中的一种。它用于解决共享所有权的问题,并且可以避免因循环引用而导致的内存泄漏。来探知对象是否存活,并避免悬空指针的风险。并不会增加计数器来计算对象的引用次数。存在,也无法访问对象。为了判断对象是否仍然存在,如果对象已经被释放,则返回一个空的。提供了一个方法来检查其所指向的对象是否有效。,以确保对象在使用期间不会被意外释放。本身并不承担对象的所有权,它指向由。管理一个整数对象,并通过。释放后,即使还有相关的。在上述示例中,我们使用。在上述示例中,我们通过。,否则返回一个有效的。原创 2023-08-27 15:06:37 · 309 阅读 · 0 评论 -
C++简单实现hash_table
对外提供insert find remove接口。使用拉链法解决hash 冲突。原创 2023-06-09 15:22:45 · 136 阅读 · 0 评论 -
vector的简单实现
emplace_back函数可以用于在vector的末尾直接构造一个元素,而不需要先创建一个临时对象再将其拷贝或移动到vector中。这个实现使用了 C++11 中的变长模板参数和完美转发,可以接受任意数量和类型的参数,并将它们转发给。的大小,并使用了移动构造和拷贝构造函数来实现对象的拷贝和移动。的末尾直接构造一个元素,而不需要先创建一个临时对象再将其拷贝或移动到。类的实现可以正确地处理对象的拷贝和移动,并且可以动态调整。对象,并测试了它们的各种函数。在这个实现中,我们使用了完美转发来将。原创 2023-06-07 23:54:13 · 572 阅读 · 0 评论 -
shared_ptr的简单实现
shared_ptr是一种非常实用的智能指针,它可以在多个指针之间共享同一个对象,从而避免了内存泄漏和野指针的问题。变量可以被多个变量共享,但是这种共享方式是基于静态存储期的,而不是基于动态存储期的。是 C++11 中引入的一种智能指针,它可以在多个指针之间共享同一个对象,从而避免了内存泄漏和野指针的问题。变量来记录引用计数无法实现动态存储期的共享,从而导致引用计数的不准确和内存泄漏的问题。的值为 0,则表示没有任何指针指向该对象,此时会自动释放该对象的内存空间。时,我们需要的是动态存储期的共享,即多个。原创 2023-06-06 12:46:29 · 1388 阅读 · 2 评论 -
std::forward_list与std::advance使用
是一个非常实用的算法函数,它可以帮助我们在迭代器中快速移动指定的距离,非常适合于需要在迭代器中进行随机访问的场景。但是,由于它可能会导致迭代器越界,因此在使用时需要格外小心,避免出现不必要的错误。是 C++ STL 中的一个算法函数,它可以将迭代器向前或向后移动指定的距离。的用法非常简单,它接受两个参数:一个迭代器和一个整数值,表示要移动的距离。的用法与其他 STL 容器类似,可以使用迭代器来遍历和操作容器中的元素。的绝对值大于迭代器中剩余的元素个数,那么行为是未定义的。表示要移动的迭代器,原创 2023-05-23 12:32:42 · 645 阅读 · 0 评论 -
std::inner_product与std::accumulate初始值设置踩坑
std::transform_reduce函数:在计算序列的变换和缩减时,初始值的类型应该与变换和缩减函数的返回类型相同,否则可能会导致类型转换错误或精度损失。std::partial_sum函数:在计算序列的部分和时,初始值的类型应该与序列的元素类型相同,否则可能会导致类型转换错误或精度损失。std::reduce函数:在计算序列的缩减时,初始值的类型应该与缩减函数的返回类型相同,否则可能会导致类型转换错误或精度损失。函数将对两个源序列中的每个元素进行乘法运算,并将结果累加到初始值中,最终返回累加结果。原创 2023-04-12 23:57:43 · 764 阅读 · 0 评论 -
【C++】std::transform、std::back_inserter使用
std::transform函数可以用于对一个序列中的每个元素进行转换,并将结果存储到另一个序列中。std::back_inserter是一个迭代器适配器,可以将元素插入到容器的末尾原创 2023-04-12 23:40:25 · 882 阅读 · 0 评论 -
__builtin_xxx指令学习【5】__builtin_bswap16/32/64
__builtin_bswap16/32/64是GCC和Clang编译器提供的内置函数,用于交换一个整数的字节顺序。其中,__builtin_bswap16用于交换一个16位整数的字节顺序,__builtin_bswap32用于交换一个32位整数的字节顺序,__builtin_bswap64用于交换一个64位整数的字节顺序。这些函数的使用背景是在一些网络编程和底层编程中,需要对字节序进行处理和转换,而交换字节顺序是一个常见的操作原创 2023-04-08 17:33:16 · 2902 阅读 · 0 评论 -
__builtin_xxx指令学习【4】__builtin_clz&__builtin_ctz & __builtin_clzll & __builtin_ctzll
__builtin_clz是GCC和Clang编译器提供的一个内置函数,用于计算一个整数的二进制表示中,从最高位开始连续的0的个数。该函数的使用背景是在一些位运算和计算机视觉等领域中,需要对二进制数据进行处理和分析。原创 2023-04-08 17:29:15 · 3491 阅读 · 0 评论 -
__builtin_xxx指令学习【3】__builtin_popcount & __builtin_popcountll
__builtin_popcount是GCC和Clang编译器提供的一个内置函数,用于计算一个整数中二进制位为1的个数。该函数的使用背景是在一些位运算和计算机视觉等领域中,需要对二进制数据进行处理和分析原创 2023-04-08 17:30:23 · 871 阅读 · 0 评论 -
__builtin_xxx指令学习【2】__builtin_prefetch
__builtin_prefetch是GCC编译器提供的一个内置函数,用于预取数据到CPU的缓存中,以便提高程序的执行效率原创 2023-04-08 17:25:47 · 2246 阅读 · 0 评论 -
__builtin_xxx指令学习【1】__builtin_expect
__builtin_expect是GCC编译器提供的一个内置函数,用于告诉编译器一个分支的执行概率,以便编译器在生成机器码时进行优化。原创 2023-04-08 16:47:06 · 782 阅读 · 0 评论 -
std::set_difference用法
其中,first1 和 last1 表示第一个有序范围的起始和结束迭代器,first2 和 last2 表示第二个有序范围的起始和结束迭代器,d_first 表示结果范围的起始迭代器。std::set_difference 是 C++ STL 中的一个算法,用于计算两个有序范围之间的差集,并将结果存储到另一个有序范围中。需要注意的是,输入范围必须是有序的,否则 std::set_difference 算法的行为是未定义的。另外,结果范围必须足够大,以容纳所有的差集元素。原创 2023-04-06 22:14:00 · 997 阅读 · 0 评论 -
c++中以类对象作为key用于unordered_map、map,以及std::tie技巧使用
在这个例子中,std::tie 函数将 country_id、province_id 和 isp_id 绑定在一起,形成一个元组。当比较多个成员变量时,可以使用 std::tie 函数来简化比较操作。std::tie 函数可以将多个变量绑定在一起,形成一个元组,然后使用元组的比较操作符进行比较。需要注意的是结构体的成员变量应该是不可变的,以避免在哈希表or红黑树中修改键值对。如果在哈希表or红黑树中修改键值对,将会导致哈希表or红黑树的内部结构被破坏,从而导致未定义的行为。原创 2023-04-06 21:14:55 · 908 阅读 · 0 评论 -
c++实现日志类(写入logfile)
【代码】c++实现日志类(写入logfile)原创 2023-04-04 00:14:24 · 271 阅读 · 0 评论 -
c++使用regex报错regex_error
编译时无报错,运行时抛异常regex_errorcheck后发现,gcc版本4.9以上才能使用std::regex 而我们一般gcc版本是4.8.5 所以这里不采用std::regex,gcc版本升级不现实,可采取的方案有两个:1、使用boost::regex2、使用inet_pton判断ip。原创 2023-03-25 04:31:09 · 1231 阅读 · 0 评论 -
error: non-member function ‘XXX::IsValid(const T&)’ cannot have cv-qualifier
然后,我们定义了一个名为 IsValid 的全局函数,它接受一个对象作为参数,并将该对象传递给 Validator 类的构造函数。要解决这个错误,你需要将 IsValid 函数定义为一个成员函数或者一个全局函数,而不是一个非成员函数。如果你想将 IsValid 定义为一个成员函数,那么你需要将它添加到一个类中,并将需要检查的对象作为该类的成员变量。如果你不想将 IsValid 定义为一个成员函数,那么你可以将它定义为一个全局函数,并将需要检查的对象作为参数传递给它。原创 2023-03-25 04:03:49 · 367 阅读 · 0 评论 -
返回引用与返回值与返回std::move(obj)
需要注意的是,返回引用也有一些潜在的问题,比如返回了一个指向已经被销毁的对象的引用,或者返回了一个指向私有成员的引用等。因此,在使用返回引用时需要特别小心,确保返回的引用是有效的、安全的,并且不会对对象的状态造成任何影响。但是,返回引用需要确保返回的引用是有效的、安全的,并且不会对对象的状态造成任何影响,否则可能会导致程序崩溃或者产生不可预期的结果。因此,如果你需要返回一个对象的引用,并且该对象的生命周期与函数的生命周期相同,那么返回引用可能是更优雅的方式。原创 2023-03-25 03:33:12 · 487 阅读 · 0 评论 -
C++实现读写分离的双缓冲buffer
读写分离的双缓冲buffer有以下好处:1. 提高了并发读写的效率:在多线程环境下,读写操作是相互竞争的,读写分离的双缓冲buffer可以有效地减少读写之间的竞争,提高并发读写的效率。2. 减少了数据的拷贝:双缓冲buffer可以将数据从写缓冲区直接拷贝到读缓冲区,避免了中间数据拷贝的过程,提高了数据读写的效率。3. 提高了数据的安全性:双缓冲buffer可以避免读写操作的交叉,从而保证了数据的安全性。4. 提高了系统的稳定性:双缓冲buffer可以避免读写操作的阻塞,从而提高了系统的稳定性和可靠性原创 2023-03-22 23:20:48 · 3095 阅读 · 0 评论 -
c++判断文件是否存在
可以使用C++的文件流来判断文件是否存在。原创 2023-03-22 23:10:11 · 1543 阅读 · 0 评论 -
c++用vector实现定长队列
我们可以用queue或vector实现定长队列,但是如果我们有遍历定长队列的需求的话,使用queue不是一个好的选择,因为queue本身不支持。这里分别提供queue和vector的实现原创 2023-03-22 23:06:19 · 1529 阅读 · 0 评论 -
C++使用rapidjson进行类的序列化与反序列化
C++中可以使用第三方库来实现将类序列化成JSON文件,以及读取JSON文件内容反序列化为类对象。使用的话也比较简单,拉下代码,然后将rapidjson-master/include/rapidjson目录拉到自己文件目录下,然后在编译参数上加上即可。原创 2023-03-22 22:54:16 · 990 阅读 · 0 评论 -
C++将类序列化和反序列化到共享内存
【代码】C++将类序列化和反序列化到共享内存。原创 2023-03-22 22:40:06 · 220 阅读 · 0 评论 -
std::copy与memcpy比较
std::copy和memcpy都可以用于内存块之间的复制操作,但有几个重要的异同点,这里记录一下原创 2023-03-12 19:19:45 · 5157 阅读 · 1 评论 -
c++ 常见宏、模板用法【1】
记录几个常见的好用的宏和模板编程技巧的示例,它们可以提高代码的可读性、可维护性和灵活性,为开发人员提供了更多的选择和工具来处理复杂的编程问题。原创 2023-03-12 00:20:44 · 613 阅读 · 0 评论 -
C++预处理连接
C++预处理连接(Preprocessor Concatenation)是一种宏定义技巧,用于将两个或多个符号(如变量、字符串等)连接成一个符号。这种技巧可以帮助程序员编写更加灵活和可维护的代码,尤其是在宏定义中使用较为常见。原创 2023-03-11 22:49:14 · 1413 阅读 · 3 评论 -
swap释放vector内存
int main() { vector<int> vec; for (int i = 0; i < 1000; i++) { vec.emplace_back(i); } cout << "capacity:" << vec.capacity() << " size:" << vec.size() << endl; vec.clear(); cout <<原创 2022-05-29 13:05:06 · 3584 阅读 · 2 评论 -
c++常见的10个类&对象问题
1、对象的浅复制2、构造函数中的操作符重载3、拷贝构造函数不能模板化4、析构函数未捕获异常导致coredump5、构造函数抛出异常6、基类析构函数非虚导致内存泄漏7、删除void*指针引发内存泄露8、成员函数尾部缺失const9、使用memset初始化class10、对象向下转换失败原创 2022-05-28 16:51:23 · 731 阅读 · 0 评论 -
c/c++常见类型转换错误
文章目录char转int 高位符号扩展有符号int与无符号int比较关于一个bit的位域变量的取值范围临时变量溢出size_t死循环char转int 高位符号扩展int main() { char a = 0x9A; int util; util = (int)a; cout << a << endl; cout << util << endl; if (util > 0) { st.原创 2022-05-27 14:40:41 · 3728 阅读 · 0 评论 -
C语言技巧:把单一元素的数组放在末尾,struct可以拥有可变大小的数组
《C++ 对象模型》第19页有这样一句话C程序员的巧计有时候却成为c++程序员的陷阱。例如把单一元素的数组放在一个struct的末尾,于是每个struct objects可以拥有可变数组的数组:struct mumble{ /* stuff */ char pc[1]; }; //从文件或标准输入装置中取得一个字符串//然后为struct 本身和该字符配置足够的内存 struct mumble * pmumbl = (struct mumble*)原创 2022-03-30 15:34:26 · 1448 阅读 · 0 评论 -
c++关于虚表的一些笔记
文章目录1、虚函数表指针2、多态构成的条件3、重载、重写、重定义 三者区别4、继承与虚函数5、单继承中的虚函数表无虚函数覆盖有虚函数覆盖6、单继承中的虚函数表无虚函数覆盖有虚函数覆盖参考看《深度探索c++对象模型》的时候对虚表有了点疑惑,正好网上有些文章解除了这个疑惑,记录一下1、虚函数表指针在64位操作系统下当我们计算包含虚函数的类大小时,我们会发现不管类中有几个虚函数,类的大小都会比没有虚函数时类的大小大8,这是因为存了一个指向虚表的指针,大小为8字节。对象中的这个指针我们叫做虚函数表指针,虚函原创 2022-03-30 14:49:07 · 1357 阅读 · 0 评论