您当前的位置: 首页 >  c++

鱼儿-1226

暂无认证

  • 0浏览

    0关注

    1100博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

10分钟速览 C++20 新增特性

鱼儿-1226 发布时间:2021-01-26 17:32:10 ,浏览量:0

C++20 新增特性​jimmysue.me

  • 新增关键字(keywords)
  • 新增标识符(Identifies)
  • 模块(Modules)
    • 优点
    • 创建模块
    • 引用模块
    • import 头文件
  • Ranges
    • 例子
  • 协程(Coroutines)
    • 什么是协程
    • 例子(VC++)
  • Concepts
    • 如何定义
    • 使用
    • 例子
  • Lambda 表达式的更新
    • [=, this] 需要显式捕获this变量
    • 模板形式的 Lambda 表达式
    • Lambda 表达式打包捕获(Pack Expansion)
  • 常量表达式(constexpr) 的更新
    • constexpr string & vector
  • 原子(Atomic)智能指针
    • 例子
  • 自动合流(Joining), 可中断(Cancellable) 的线程
    • 例子
  • C++20 同步(Synchronization)库
    • std::atomic_ref
  • 其他更新
    • 指定初始化(Designated Initializers)
    • 航天飞机操作符
    • 范围 for 循环语句支持初始化
    • 非类型模板形参支持字符串
    • [[likely]], [[unlikely]]
    • 日历(Calendar)和时区(Timezone)功能
    • std::span
    • 特性测试宏
    • consteval 函数
    • constinit
    • 用 using 引用 enum 类型
    • 格式化库(std::format)
    • 增加数学常量
    • std::source_location
    • [[nodiscard(reason)]]
    • 位运算
    • 一些小更新
  • 参考资料
新增关键字(keywords)
  • concept
  • requires
  • constinit
  • consteval
  • co_await
  • co_return
  • co_yield
  • char8_t
新增标识符(Identifies)
  • import
  • module
模块(Modules) 优点
  • 没有头文件
  • 声明实现仍然可分离, 但非必要
  • 可以显式指定那些导出(类, 函数等)
  • 不需要头文件重复引入宏 (include guards)
  • 模块之间名称可以相同不会冲突
  • 模块只处理一次, 编译更快 (头文件每次引入都需要处理)
  • 预处理宏只在模块内有效
  • 模块引入顺序无关紧要
创建模块
// cppcon.cpp 
export module cppcon; 
namespace CppCon { 
    auto GetWelcomeHelper() {  return "Welcome to CppCon 2019!";  } 
    export auto GetWelcome() { return GetWelcomeHelper();} 
}
引用模块
// main.cpp 
import cppcon; 
int main(){ 
    std::cout next = head; 
        while (!head.compare_exchange_weak(p->next, p)){ 
    } // C++11: atomic_compare_exchange_weak(&head, &p->next, p); }     
    void pop_front() { 
        auto p = head.load(); 
        while (p && !head.compare_exchange_weak(p, p->next)) {
        } // C++11: atomic_compare_exchange_weak(&head, &p, p->next); 
    } 
};

例子来自 Herb Sutter 的 N4162 论文

自动合流(Joining), 可中断(Cancellable) 的线程
  • std::jthread
    • 头文件
    • 支持中断
    • 析构函数中自动 Join
      • 析构函数调用 stop_source.request_stop() 然后 join()
  • 中断线程执行
    • 头文件
    • std::stop_token
      • 用来查询线程是否中断
      • 可以和condition_variable_any配合使用
    • std::stop_source
      • 用来请求线程停止运行
      • stop_resources 和 stop_tokens 都可以查询到停止请求
    • std::stop_callback
      • 如果对应的stop_token 被要求终止, 将会触发回调函数
      • 用法: std::stop_callback myCallback(myStopToken, []{ /* … */ });
例子
  • 自动合流 Join
std::thread 在析构函数中如果线程  joinable()  会直接调用  std::terminate()  直接导致程序退出
void DoWorkPreCpp20() { 
    std::thread job([] { /* ... */ }); 
    try { 
        // ... Do something else ... 
    } catch (...) { 
        job.join(); 
        throw; // rethrow 
    } 
    job.join(); 
} 

void DoWork() { 
    std::jthread job([] { /* ... */ }); 
    // ... Do something else ... 
} // jthread destructor automatically calls join()
  • 中断
std::jthread job([](std::stop_token token) {
    while (!token.stop_requested()) { 
        //... 
    } 
}); 
//... job.request_stop(); 
// auto source = job.get_stop_source() 
// auto token = job.get_stop_token()
C++20 同步(Synchronization)库
  • 信号量(Semaphore), 维基百科请走这里
    • 头文件
    • 轻量级的同步原语
    • 可用来实现任何其他同步概念, 如: mutex, latches, barriers, …
    • 两种类型:
      • 多元信号量(counting semaphore): 建模非负值资源计数
      • 二元信号量(binary semaphore): 只有一个插孔, 两种状态, 最适合实现mutex
  • std::atomic 等待和通知接口
    • 等待/阻塞在原子对象直到其值发生改变, 通过通知函数发送通知
    • 比轮训(polling)来的更高效
    • 方法
      • wait()
      • notify_one()
      • notify_all()
  • 锁存器(Latch)和屏障(Barrier)
    • 辅助线程条件同步
  • 锁存器(Latches)
    • 头文件
    • 线程的同步点
      • 线程将阻塞在这个位置, 直到到达的线程个数达标才放行, 放行之后不再关闭
    • 锁存器只会作用一次
  • 屏障(Barriers)
    • 多个阶段
    • 每个阶段中
      • 一个参与者运行至屏障点时被阻塞,需要等待其他参与者都到达屏障点, 当到达线程数达标之后
      • 阶段完成的回调将被执行
      • 线程计数器被重置
      • 开启下一阶段
      • 线程得以继续执行
std::atomic_ref
  • 头文件
  • Atomic 引用
  • 通过引用访问变为原子操作, 被引用对象可以为非原子类型
其他更新 指定初始化(Designated Initializers)
struct Data { 
    int anInt = 0; 
    std::string aString; 
}; 
Data d{ .aString = "Hello" };
航天飞机操作符
  • 正规名称: 三路比较运算符
  • 三路比较结果如下
    • (a b) < 0 // 如果 a < b 则为 true
    • (a b) > 0 // 如果 a > b 则为 true
    • (a b) == 0 // 如果 a 与 b 相等或者等价 则为 true
  • 类似于C的strcmp 函数返回-1, 0, 1
  • 一般情况: 自动生成所有的比较操作符, 如果对象是结构体则逐个比较, 可以用下面代码代替所有的比较运算符
    • auto X::operator(const Y&) = default;
  • 高级情况: 指定返回类型(支持6种所有的比较运算符)

示例:

class Point { 
    int x; int y; 
public: 
    friend bool operator==(const Point& a, const Point& b){ 
        return a.x==b.x && a.y==b.y; 
    } 
    friend bool operator< (const Point& a, const Point& b){ 
        return a.x < b.x || (a.x == b.x && a.y < b.y);  
    } 
    friend bool operator!=(const Point& a, const Point& b) { 
        return !(a==b); 
    } 
    friend bool operator            
关注
打赏
1604459285
查看更多评论
0.0415s