…
- C++标准保证把 std::vector 的元素排列跟数组一样,因此可以这样用:
&*my_array.begin()
取到相应的数组. auto it = std::max_element(v.begin(), v.end())
取到最大元素的iterator- std::move() 将变量变为右值引用,使之应用右值构造或右值移动
- std::ref() 在传参的时候使用,比如 std::bind() 的时候,传递引用参数
- std::promise<> 传给工作线程,std::fucture<> 从 promise 中获取结果,用于线程间同步
- mutable在lambda表达式中,表示传进去的值可以在表达式内部被修改
使用std::bind()替换lambda
比如一个第三方接口是这样的:
1 | typedef std::function<void(TimerID)> TimerCallback; |
可以这样调用:
1 | setInterval(300, [100](TimerID timeId){ |
现在可以这样调用:
1 | static void onTimer(TimerID timerID, int n) { |
原先使用lambda捕获的临时参数,现在可以使用std::bind()
绑定进去
PS. LoadLibrary/dlopen最大的问题就是它们可能会跳过全局初始化的部分,也就是说,所有“逻辑上”应该在
main
之前执行的部分有可能根本就不会执行,由此会带来各种各样古怪的问题很难在这儿一一详述,总之,避免全局对象+LoadLibrary/dlopen这种组合会极大的改善你的生活品质。
————————————————
版权声明:本文为CSDN博主「dongyutq」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/dongyutq/article/details/36672763
https://www.cnblogs.com/ZY-Dream/p/10068993.html
(6)一般来说,转换运算符与转换构造函数(即带一个参数的构造函数)是互逆的,如有了构造函数Test(int),那么最好有一个转换运算符int()。这样就不必提供对象参数重载运算符了,如Test a1(1);Test a2(2); Test a3; a3 = a1+a2;就不需要重载+号操作符了,因为对于a1+a2的运算,系统可能会先找有没有定义针对Test的+号操作符,如果没有,它就会找有没有针对Test类转换函数参数类型的+号操作符(因为可以将+号运行结果的类型通过转换函数转换为Test对象),因为Test类有个int类型的参数,对于int类型有+操作符,所以a1+a2真正执行的是Test(int(a1) + int(a2));即Test(3);参考 std::atomic 的实现
asio
io_service 是线程安全,可以认为是一个 epoll,调用一次 io_server.run()
异步操作分发接口
post: 异步,稍后在某个线程调用 ioc.run() 时调用;
dispatch: run_in_this_thread/post;
wrap: 等价一次dispatch, 但可以返回一个封装好的仿函数,作为其他函数的参数主循环
run(): 阻塞执行所有
run_once(): 阻塞执行1次,最多执行和分发一次异步操作,如果没有操作,就返回0, 如果执行了一次,没执行就阻塞,执行就返回1
poll_one(): 非阻塞执行1次
poll(): 非阻塞执行所有streambuf
内部有两个队列,从socket读取的数据(输出队列), 给应用层使用的队列(输入队列);或者可以理解成1个底层队列,1个应用层队列;
prepare(n): 返回子buffer,单独处理n个字符,不影响之前的buffer;从底层队列返回,不影响应用层队列指针
data(): 返回字符串形式
comsume(n): 从输入队列移除n;或者说从应用层队列移除n
commit(n): 从输出队列移除,加入输入队列;或者说从底层队列移除n,加入到应用层队列
size(): 返回大小
max_size(): 返回最大容量同步读到条件
read(sock, buf[, completion_function])
size_t completion(const boost::system::error_code & err, size_t bytes_transfered);随机读
read_at(random_stream, offset, buf [, completion_function])同步读到某个条件
read_until(sock, buf, char | string | regex | match_condition)
pair<iterator,bool> match(iterator begin, iterator end);
iterator 是 buffers_iteratorstreambuf::const_buffers_type同步写, 写完成1次后,就返回,不一定真的写完了,需要应用去处理应用层缓存
write(sock, buf [, completion_function])同步随机写
write_at(random_stream,offset, buf [, completion_function])异步读
async_read(sock, buf [, competion_function], handler)
void handler(const boost::system::error_code, size_t bytes)
sync_read_at(radom_stream, offset, buf [, completion_function] , handler)
async_read_until (sock, buf, char | string | regex | match_ condition, handler)
async_write(sock, buf [, completion_function] , handler)
async_write_at(random_stream,offset, buf [, completion_function] , handler)
gettid(), 获取线程id
1 |
std::move
- 移动语义
带指针的类在深拷贝时,会涉及大量资源的重新构造和复制,为了减少这些资源浪费, 移动语义允许将旧类的资源直接转移给新的类, 这就是c++11新增的移动; - 如何实现移动语义
使用移动构造函数, A(A &&a), 有个右值引用, 这是c++11新增的语法, 出现这个构造函数时,表示旧类的资源已经移动到新类了 - 什么时候会触发使用移动构造,也就是什么时候一个值是右值
两种情况: 1)纯右值, 字面变量、类型转换函数的返回值、lambda表达式等都是纯右值,1+3产生的临时变量也是;各种临时变量和不跟变量相关联的量; 2) 将亡值, 跟c++新增的右值引用相关的表达式, 返回右值引用T&&的函数返回值、std::move的返回值\或者转换为T&&的类型转换函数的返回值;
用于转移类中的资源
主要为了使用移动构造或者移动拷贝语义, 如果类本身没有实现移动语义, 用不用std::move都没区别
class A{
public:
A(A &&a) // 移动构造
operator =(A &&a) // 移动赋值
};
构造
拷贝构造
移动构造
拷贝赋值
移动赋值
析构函数
std::forward
在函数模板中使用, 参数接收右值, 但再传出去的时候用不成右值.
编译新版gcc
https://benjaminberhault.com//post/2018/06/22/install-gcc-on-rhel-centos-7.html
wget http://ftp.tsukuba.wide.ad.jp/software/gcc/releases/gcc-10.4.0/gcc-10.4.0.tar.gz
tar zxvf gcc-10.4.0.tar.gz
cd gcc-10.4.0
./contrib/download_prerequisites 会下载4个文件: gmp-6.1.0.tar.bz2 mpfr-3.1.6.tar.bz2 mpc-1.0.3.tar.gz isl-0.18.tar.bz2, 可以把这4个文件挪到离线环境, 重新执行该脚本(会解压)
cd ..
mkdir gcc-10.4.0-build && cd gcc-10.4.0-build
../gcc-10.4.0/configure –enable-languages=c,c++ –disable-multilib –prefix=/home/suntus/deps/gcc-10.4.0-build/install
operator bool()
if (obj)
A Very Bad Idea and should really never use it.