C++ 11 新特性总结(五):tuple元组类型
元组类型
C++越来越往Python方向靠近,以致习惯上回到纯C的时代开始使人无比痛苦。
是的,C++
11引入了元组支持,支持将任意数量的类型封装成单一对象,且在C++
17引入了auto[x,y,z] = t简单的解包方法;tuple没有size和type成员,需要std::tuple_size和std::tuple_element结合类型推导或萃取来获取大小和类型,以下:
1234567891011121314151617181920212223242526#include <iostream>#include <tuple>#include <type_traits>using namespace std;int main(){ //构造方式一: std::tuple<int, std::string, double> mytuple(0, "Eden", 1.2); //解包: cout << std::get<0>(mytuple) < ...
【sem_timedwait问题解决】系统时间向前跳变导致sem_timedwait长久阻塞
问题概述
系统时间跳变会导致一些系统时间依赖函数的异常工作,一个例子是sem_timedwait。当处于sem_timedwait阻塞等待时,如果此时系统时间跳变到起始时间之前:
1sudo date -s "2025-06-30 9:40:00" //修改系统时间
那么sem_timedwait会处于持续的阻塞状态,sem_timedwait不会返回,也不会产生任何打印效果,如下代码:
1234567891011121314151617181920212223242526272829#include <iostream>#include <time.h>#include <semaphore.h>#include <thread>using namespace std;struct timespec ts{};int main(){ sem_t sem_; sem_init(&sem_,0,0); while(true){ clo ...
boost库开发笔记(二):boost::asio异步网络编程
boost::asio
boost::asio是C++高级异步网络编程库,主要用于异步编程、调度和通讯,包括定时器、信号处理、异步执行、socket等基本功能。
本文围绕了asio入门的基础、常用接口部件等进行讨论,从简单的asio对象开始,分成异步编程和网络编程两大板块,并且相应地结合源码进行记录。本文会随着项目进展更新,相信会成为比较完备的ASIO入门体系。
boost::asio异步编程
asio::io_context
每个asio程序至少存在一个io_context对象(boost
1.66前称io_service),io_context是asio工作的核心,其提供了一个事件循环队列机制(类似Qt),作为调度器完成事件调度;io_context本身不直接与通信对象通信,而是管理一系列IO资源如定时器、socket等。
asio定时器
asio支持三种定时器,为asio::system_timer、asio::steady_timer和asio::high_resolution_timer,另一种旧版本的deadline_timer已经被弃用;其中:
as ...
C++ 11 新特性总结(四):enable_from_this/shared_from_this
问题起源
问题来自std::shared_ptr,为了保证shared_ptr的计数正确,只允许使用一个智能指针对象去使用裸指针构造,因此这样的代码是错误的:
123Person* p = new Person();std::shared_ptr<Person> p1(p);std::shared_ptr<Person> p2(p);
其后果是p在new时候执行了一次构造,p1和p2都认为自己管理了p,因此两个共享指针独立的控制块都显示引用数为1,所以析构时各自执行一次,导致双重删除:
123Person constructor called!Person destructor called!Person destructor called!
显式上我们不会这么干,但是有一些隐晦的写法还是触碰到这条红线,例如:
123456789101112131415161718192021222324#include <iostream>#include <memory>using namespace std;class Person ...
boost库开发笔记(一):boost::json使用与序列化
boost库
1998年,C++标准委员会创建了boost这个项目,初心是开发可复用的C++组件,为C++发展探索方向,boost早期严格遵循header-only原则,且代码评审规范,一度被称为最美的C++库之一,其次boost中的智能指针、regex、function/bind等一系列开发组件精华被C++标准库吸纳,成为C++事实上的重要参考库。由于boost是完全开源的,它可以前瞻性地完成一些C++开发中需要的组件,在项目上有重要应用成果。
因为项目需要,本系列会逐渐更新boost库的常用接口与原理,并持续更新。
从json方法开始。
boost::json
boost::json::value
基本数据类型构造与转换
object的value和array的成员都是以boost::json::value的形式存储,因此解析时需要重新指定数据类型才能确保类型前后一致,类似QJson的toXXX接口,基本数据类型的boost::json::value支持若干种解析转换方法:as_object、as_array、as_bool、as_double、as_int64、as_ ...
杂记:cmake版本更新/boost编译/ZMQ框架安装
Ubuntu Cmake版本更新
cmake通过bin生效,改变版本时通过软链接指向另一版本即可:
从cmake官网下载cmake-3.29.2.tar.gz,然后解压:
1sudo tar -xvzf cmake-3.29.2.tar.gz
配置编译和安装: 123sudo ./configuresudo make -j8sudo make install
此时cmake --version有可能输出新版本,也有可能保留旧版本,关键是/usr/bin/cmake的版本是什么,这里需要建立一个软链接,不要使用相对路径创建:
12sudo rm /usr/bin/cmakesudo ln -s /home/user/Desktop/cmake-3.29.2/bin/cmake /usr/bin/cmake
ubuntu下boost安装/版本更新
查看版本: 12345#方式1:若是包安装dpkg -S /usr/include/boost/version.hpp#方式2:包安装或源码安装grep "#define BOOST_LIB_VERSION&qu ...
(Private)基于发布与订阅特性的远程过程调用(RPC)网络设计
103c704d716c2a6b4b59a60c7b698e01e267a92d601a60f130246c8b57cc624af198f35b44186f916e87030c3305aea665b698f5705b3810f2c5f71a69ebd180727569d78e7ade3e120b672172d979cd8ffc903f2df6007979cb72c152cc0432e9093b6251aa47d770def05c18f970529dfe9f2b4c050f45dd60ce06dd0a91eed7eea9e622463657842c2d2364264c7051e7a4da4ec4dccc0896189016f74d0a7c60f08b0ad19c9adbceaa855c98591c3b74e871eacaf85be1785ca065d71a716c4900fe5181eb91b453432b2e0775782c8b5669a1c2c757c36b644b70c5bce2a2e7c1d4b4f5f07a0edb918c791b0fc6990eb0ede1335f04a ...
OpenCV C++记录(十一):Mat数据规范化、灰度直方图与均衡算法
归一化
讨论归一化主要是图像数据分析中用到,cv::normalize支持将Mat数据归一化:
123456789void normalize( cv::InputArray src, cv::InputOutputArray dst, double alpha = (1.0), //归一化倍数/下限,根据类型不同而不同; double beta = (0.0), //无意义或归一化上限,根据类型不同而不同,见下文; int norm_type = 4, //默认L2范数,四种方式,cv::NORM_L1/cv::NORM_L2/cv::NORM_INF/cv::NORM_MINMAX int dtype = -1, //输出矩阵类型,-1保持和原矩阵一致 cv::InputArray mask = noArray() //位置掩图,如果对src某区域归一化传入同size的mask(对应roi置白))
这里重要的地方是norm_type对应几种规范化类型,分别是L1范数(平均值)、L2范数、最大值以及范围规范化。 ...
OpenCV C++记录(十):形态学处理基础
形态学处理
在传统图像处理中,形态学处理可算是最为强大的功能之一,只要你稍微有一些粗略的识别-分类需求需要对图像进行前处理,形态学都能帮上大忙,而且具备极高的计算效率。
这得益于其计算原理的简单,腐蚀和膨胀是两种基本操作,注意这里形态学处理的对象都是二值图;
腐蚀与膨胀
腐蚀的基本原理是以二值卷积核和二值图卷积,只要一个位置的相乘结果为0,那么中心像素即为0:
腐蚀基本运算
腐蚀函数原型是: 123456789void erode( cv::InputArray src, //输入二值图像 cv::OutputArray dst, //输出二值图像 cv::InputArray kernel, //卷积核 cv::Point anchor = cv::Point(-1, -1), //处理锚点,默认中心点 int iterations = 1, //腐蚀次数 int borderType = 0, //边值处理:默认常数填充 const cv::Scalar &borderValue = morphologyD ...
OpenCV C++记录(九):二值化与图像模糊(滤波)算法
二值化
全局阈值
将灰度图二值化是图像处理基本操作,比较简单: 1234567double threshold( InputArray src, //输入灰度图 OutputArray dst, //输出二值图 double thresh, //分割阈值 double maxval, //最大阈值,是否生效与类型相关 int type //二值化类型);
二值化类型包括:
THRESH_BINARY:普通二值化,像素大于thresh的设为maxval,其余为0;
THRESH_BINARY_INV:反二值化,像素大于thresh的设为0,其余为maxval;
THRESH_TRUNC:截断二值化,像素大于thresh设置为thresh,其余不变;
THRESH_TOZERO:零二值化,像素大于thresh则不变,其余为0;
THRESH_TOZERO_INV:反的零二值化,像素大于thresh设置为0,其余不变;
THRESH_OTSU:大津法,适用于双峰图像;
...