0%

cpp相关

  1. C++标准保证把 std::vector 的元素排列跟数组一样,因此可以这样用: &*my_array.begin() 取到相应的数组.
  2. auto it = std::max_element(v.begin(), v.end()) 取到最大元素的iterator
  3. std::move() 将变量变为右值引用,使之应用右值构造或右值移动
  4. std::ref() 在传参的时候使用,比如 std::bind() 的时候,传递引用参数
  5. std::promise<> 传给工作线程,std::fucture<> 从 promise 中获取结果,用于线程间同步
  6. mutable在lambda表达式中,表示传进去的值可以在表达式内部被修改

使用std::bind()替换lambda

比如一个第三方接口是这样的:

1
2
typedef std::function<void(TimerID)>    TimerCallback;
TimerID setInterval(int interval_ms, TimerCallback cb);

可以这样调用:

1
2
3
setInterval(300, [100](TimerID timeId){
printf("tid=%ld timerID=%lu time=%lus n=%d\n", hv_gettid(), (unsigned long)timerID, (unsigned long)time(NULL), n);
});

现在可以这样调用:

1
2
3
4
5
static void onTimer(TimerID timerID, int n) {
printf("tid=%ld timerID=%lu time=%lus n=%d\n", hv_gettid(), (unsigned long)timerID, (unsigned long)time(NULL), n);
}

setInterval(300, std:bind(onTimer, std::placeholders::_1, 100));

原先使用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
2
#include <sys/syscall.h>
#define gettid() syscall(__NR_gettid)

std::move

  1. 移动语义
    带指针的类在深拷贝时,会涉及大量资源的重新构造和复制,为了减少这些资源浪费, 移动语义允许将旧类的资源直接转移给新的类, 这就是c++11新增的移动;
  2. 如何实现移动语义
    使用移动构造函数, A(A &&a), 有个右值引用, 这是c++11新增的语法, 出现这个构造函数时,表示旧类的资源已经移动到新类了
  3. 什么时候会触发使用移动构造,也就是什么时候一个值是右值
    两种情况: 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.