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的整数序列。

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

相关推荐
Proxy_ZZ0几秒前
用Matlab绘制BER曲线对比SPA与Min-Sum性能
人工智能·算法·机器学习
黎阳之光1 分钟前
黎阳之光:以视频孪生领跑全球,赋能数字孪生水利智能监测新征程
大数据·人工智能·算法·安全·数字孪生
小李子呢021122 分钟前
前端八股6---v-model双向绑定
前端·javascript·算法
史迪仔011239 分钟前
[QML] QML IMage图像处理
开发语言·前端·javascript·c++·qt
2301_822703201 小时前
Flutter 框架跨平台鸿蒙开发 - 创意声音合成器应用
算法·flutter·华为·harmonyos·鸿蒙
cmpxr_2 小时前
【C】数组名、函数名的特殊
c语言·算法
KAU的云实验台2 小时前
【算法精解】AIR期刊算法IAGWO:引入速度概念与逆多元二次权重,可应对高维/工程问题(附Matlab源码)
开发语言·算法·matlab
会编程的土豆2 小时前
【数据结构与算法】再次全面了解LCS底层
开发语言·数据结构·c++·算法
低频电磁之道2 小时前
解决 Windows C++ DLL 导出类不可见的编译错误
c++·windows
大熊背3 小时前
如何利用Lv值实现三级降帧
算法·自动曝光·lv·isppipeline