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

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

相关推荐
weixin_478689761 分钟前
C++ 对 C 的兼容性
java·c语言·c++
k要开心7 分钟前
C++概念以及基础框架语法
开发语言·c++
hn小菜鸡18 分钟前
LeetCode 1356.根据数字二进制下1的数目排序
数据结构·算法·leetcode
zhuiQiuMX23 分钟前
分享今天做的力扣SQL题
sql·算法·leetcode
weixin_3077791328 分钟前
Linux下GCC和C++实现统计Clickhouse数据仓库指定表中各字段的空值、空字符串或零值比例
linux·运维·c++·数据仓库·clickhouse
music&movie2 小时前
算法工程师认知水平要求总结
人工智能·算法
秦少游在淮海2 小时前
C++ - string 的使用 #auto #范围for #访问及遍历操作 #容量操作 #修改操作 #其他操作 #非成员函数
开发语言·c++·stl·string·范围for·auto·string 的使用
const5442 小时前
cpp自学 day2(—>运算符)
开发语言·c++
虾球xz2 小时前
CppCon 2015 学习:CLANG/C2 for Windows
开发语言·c++·windows·学习
laocui12 小时前
Σ∆ 数字滤波
人工智能·算法