c++20 的部分新概念及代码

1 概念(concepts)

cpp 复制代码
#include <iostream>
#include <concepts>

template<typename T>
concept Integral = std::is_integral_v<T>;

template<Integral T>
T add(T a, T b) {
    return a + b;
}

int main() {
    std::cout << add(5, 3) << std::endl;  // 输出:8
    // std::cout << add(3.5, 2.7) << std::endl;  // 错误:不满足Integral概念的要求
    return 0;
}

定义了一个概念(Integral),用于限定模板参数必须是整数类型。然后,我们定义了一个模板函数add,它接受两个满足Integral概念的参数,并返回它们的和。在main函数中,我们展示了如何使用这个模板函数来执行整数相加操作,而当传递非整数类型参数时,编译器会产生错误,因为不满足概念的要求

2三路比较运算符(<=>)

cpp 复制代码
#include <compare>
#include <iostream>

struct Point {
    int x;
    int y;

    auto operator<=>(const Point&) const = default; // 默认实现三路比较运算符
};

int main() {
    Point p1 {3, 4};
    Point p2 {5, 2};

    auto result = p1 <=> p2;
    
    if (result == std::strong_ordering::equal) {
        std::cout << "p1 equals p2" << std::endl;
    } else if (result == std::strong_ordering::less) {
        std::cout << "p1 is less than p2" << std::endl;
    } else {
        std::cout << "p1 is greater than p2" << std::endl;
    }

    return 0;
}

我们定义了一个Point结构体,它有两个整数成员变量x和y。我们使用默认的operator<=>实现了三路比较运算符。在main函数中,我们创建了两个Point对象p1和p2,并比较它们的大小关系。根据比较结果,我们输出相应的消息。

使用三路比较运算符可以简化代码,并使得比较操作更加直观和易于理解。

3 初始化捕获扩展(init-capture extension)

允许在lambda表达式中使用初始化器列表来捕获变量。这使得在lambda表达式中可以方便地捕获并初始化变量,而不需要额外的类成员或者在捕获列表中使用引用捕获

cpp 复制代码
#include <iostream>

int main() {
    int x = 5;
    int y = 10;

    auto lambda = [x = x + 1, &y = y]() {
        std::cout << "x: " << x << ", y: " << y << std::endl;
    };

    x = 100;
    y = 200;

    lambda(); // 输出:x: 6, y: 200

    return 0;
}

创建了一个lambda表达式lambda,它通过初始化捕获方式捕获了变量xyx通过值捕获,并在捕获时增加了1,而y则通过引用捕获。在lambda表达式中,我们输出了捕获的变量xy的值。即使在lambda表达式创建后,我们修改了原始变量xy的值,但是lambda表达式中捕获的值仍然保持了捕获时的状态。

初始化捕获扩展使得lambda表达式更加灵活,并且可以更方便地控制捕获的变量的初始化过程

4 协程(coroutines)

它是一种轻量级的线程,可以暂停和恢复执行,而不会阻塞整个线程。使用协程可以方便地实现异步编程,简化了复杂的异步代码

cpp 复制代码
#include <iostream>
#include <coroutine>

struct Generator {
    struct promise_type {
        int current_value;

        auto initial_suspend() {
            return std::suspend_always{};
        }

        auto final_suspend() noexcept {
            return std::suspend_always{};
        }

        Generator get_return_object() {
            return Generator{std::coroutine_handle<promise_type>::from_promise(*this)};
        }

        void return_void() {}

        auto yield_value(int value) {
            current_value = value;
            return std::suspend_always{};
        }

        void unhandled_exception() {
            std::terminate();
        }
    };

    std::coroutine_handle<promise_type> coroutine;

    explicit Generator(std::coroutine_handle<promise_type> coro) : coroutine(coro) {}

    ~Generator() {
        if (coroutine) {
            coroutine.destroy();
        }
    }

    bool move_next() {
        coroutine.resume();
        return !coroutine.done();
    }

    int current_value() const {
        return coroutine.promise().current_value;
    }
};

Generator generate_range(int from, int to) {
    for (int i = from; i <= to; ++i) {
        co_yield i;
    }
}

int main() {
    auto generator = generate_range(1, 5);
    while (generator.move_next()) {
        std::cout << generator.current_value() << std::endl;
    }
    return 0;
}

定义了一个生成器Generator,它通过协程来生成一个指定范围内的整数序列。generate_range函数是一个协程函数,它使用co_yield语句来产生序列中的每个值。在main函数中,我们使用生成器来生成并输出从1到5的整数序列。

协程提供了一种简单而强大的方式来实现异步编程,使得代码更具可读性和可维护性。

相关推荐
Jerry31 分钟前
LeetCode 209. 长度最小的子数组
算法
汉克老师1 小时前
GESP2026年6月认证C++六级( 第三部分编程题(2、满二叉树))精讲
c++·深度优先·树形dp·满二叉树·gesp六级·树形dfs
彦为君1 小时前
算法思维与经典智力题
java·前端·redis·算法
智能优化与强化学习1 小时前
Gym(Gymnasium)仿真环境详解(二):环境简介、入门算法、调参要点、核心挑战
算法·强化学习·gym·零基础入门·算法评估
mxwin1 小时前
Unity Shader exp 函数的算法与渲染应用
算法·unity·游戏引擎·shader
“码”力全开1 小时前
AI视频分析误报优化完整流程
算法·架构·边缘计算
深盾科技_Virbox1 小时前
深盾科技·Virbox产品体系全景解读:软件安全如何从加密锁走向全生命周期
java·大数据·算法·安全·软件需求
踮起脚看烟花2 小时前
多人聊天室实现v2.0
c++·信息与通信
梦帮科技2 小时前
UE5 GAS 实战:用 Gameplay Ability System 搭建「赛博修真」境界与技能体系
c++·人工智能·python·ue5·c#
旖-旎2 小时前
QT系统篇(5)(下)
开发语言·c++·qt