c++20:范围(Ranges)

c++20:范围(Ranges)

1.概要

2.内容

C++20 引入了一系列称为“范围(Ranges)”的新特性,这些特性为处理容器和范围提供了更简洁、更高效的方法。范围库主要包括视图(views)、操作(actions)和算法(algorithms)三个部分,旨在提高代码的可读性和性能。

视图(Views)

视图是轻量级的、不可变的范围适配器,它们可以对现有范围进行转换或过滤,生成新的范围。以下是一些常用的视图:

std::ranges::views::all:

返回一个表示整个范围的视图。 std::ranges::views::filter:

根据谓词对范围进行过滤。 auto even_numbers = std::ranges::views::filter(numbers, [](int n) { return n % 2 == 0; }); std::ranges::views::transform:

对范围中的每个元素应用一个函数,并生成一个新的范围。 auto squares = std::ranges::views::transform(numbers, [](int n) { return n * n; }); std::ranges::views::slice:

截取范围中的一部分。 auto slice_of_numbers = std::ranges::views::slice(numbers, 1, 5);

操作(Actions)

操作是对范围执行某些操作的对象,例如将范围转换为容器,或者对范围中的元素进行排序。

std::ranges::to_vector:

将范围转换为 std::vector。 std::vector vec = std::ranges::to_vector(numbers); std::ranges::sort:

对范围进行排序。 std::ranges::sort(numbers);

算法(Algorithms)

C++20 范围库中的算法是对标准算法库()的扩展,旨在与范围更好地协作。

std::ranges::find:

在范围中查找元素。 auto it = std::ranges::find(numbers, 42); std::ranges::for_each:

对范围中的每个元素应用一个函数。 std::ranges::for_each(numbers, [](int n) { std::cout << n << " "; }); std::ranges::count:

计算范围内等于某值的元素数量。auto count = std::ranges::count(numbers, 42);

示例代码

以下是一个使用范围库的简单示例:

#include

#include

#include

int main() {

std::vector numbers = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};

// 使用 views::filter 过滤出偶数

auto even_numbers = std::ranges::views::filter(numbers, [](int n) { return n % 2 == 0; });

// 使用 views::transform 将每个偶数平方

auto squares = std::ranges::views::transform(even_numbers, [](int n) { return n * n; });

// 将结果转换为 vector 并输出

std::vector result = std::ranges::to_vector(squares);

for (int n : result) {

std::cout << n << " ";

}

return 0;

}

总结

C++20 的范围库提供了一种更现代化、更简洁的方式来处理范围操作,极大地提高了代码的可读性和维护性。通过视图、操作和算法的组合,可以轻松地实现复杂的范围处理逻辑。

3.关联链接

c++模块(Modules)-CSDN博客

c++20:概念(Concepts)-CSDN博客

c++20:范围(Ranges)-CSDN博客

c++20:协程(Coroutines)-CSDN博客

c++20:协程(Coroutines)-CSDN博客

c++协程(Coroutines)-无限的整数序列-CSDN博客

三路比较运算符(Spaceship Operator)-CSDN博客

std::format-CSDN博客

c++20,位操作增强-CSDN博客

c++20 空指针比较-CSDN博客

4.关联知识

1.c++20有什么新功能

C++20 是 C++ 标准的一个重要更新,它引入了许多新特性和改进,显著提升了语言的功能性和易用性。以下是一些关键的新功能:

一、模块(Modules)

功能:改变了组织源码文件的方式,旨在替换传统的头文件 #include 模型,以减少编译时间和改善依赖管理。在项目中,不再需要区分 .cpp 和 .h 文件。示例:

// my_module.module

export module my_module;

export void greet() {

std::cout << "Hello from the module!" << std::endl;

}

// main.cpp

import my_module;

int main() {

greet();

return 0;

}

二、概念(Concepts)

功能:允许在编译时精确指定模板参数需满足的条件,增强编译时错误信息和泛型编程的清晰度。示例:

#include

template

concept Integral = std::is_integral_v;

template

T abs(T x) {

return x >= 0 ? x : -x;

}

int main() {

static_assert(abs(42) == 42);

static_assert(abs(-42) == 42);

// static_assert(abs(42.0) == 42.0); // 错误,double不满足Integral概念

}

三、范围(Ranges)

功能:扩展了标准库中的算法,支持更简洁、更灵活的序列操作。Ranges 库是对标准模板库(STL)的一个重要扩展,它重新定义了容器和算法的交互方式,使代码更具可读性和表达力。示例:

#include

#include

int main() {

std::vector vec = {1, 2, 3, 4, 5, 6};

auto even = vec | ranges::view::filter([](int x) { return x % 2 == 0; });

for (int val : even) {

std::cout << val << " ";

}

return 0;

}

四、协程(Coroutines)

功能:正式支持协程,使得编写异步代码更为直观。协程是一种特殊的函数,允许在执行过程中暂停并在稍后恢复。示例(简化的生成器示例):

#include

#include

struct Generator {

struct promise_type;

using handle_t = std::coroutine_handle;

Generator(handle_t h) : coro(h) {}

~Generator() {

if (coro) coro.destroy();

}

int next() {

coro.resume();

return coro.promise().current_value;

}

private:

handle_t coro;

};

struct Generator::promise_type {

int current_value{0};

Generator get_return_object() {

return Generator{handle_t::from_promise(*this)};

}

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

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

void return_value(int value) {

current_value = value;

}

void unhandled_exception() {

std::terminate();

}

};

Generator count_up_to(int limit) {

for (int i = 1; i <= limit; ++i) {

co_yield i;

}

}

int main() {

for (int val : count_up_to(5)) {

std::cout << val << " ";

}

return 0;

}

五、三路比较运算符(Spaceship Operator)

功能:引入了<=>运算符,用于实现综合比较(小于、等于、大于)。示例:

#include

struct Point {

int x, y;

auto operator<=>(const Point&) const = default;

};

int main() {

Point p1{1, 2}, p2{1, 2};

if (p1 == p2) std::cout << "Equal" << std::endl;

}

六、std::format

功能:C++20 引入的标准库函数,为字符串格式化提供了统一且强大的接口,类似于 Python 中的 str.format 或 C 的 printf 函数,但更加安全和灵活。示例:

#include

#include

int main() {

auto str = std::format("The answer is {}.", 42);

std::cout << str << std::endl; // 输出: The answer is 42.

return 0;

}

七、位操作增强

功能:C++20 对位操作进行了增强,引入了几个新函数来提高位操作的便利性和表达能力。示例(使用 std::has_single_bit 和 std::countl_zero):

#include

#include

int main() {

unsigned int num = 0b100000;

std::cout << "Is power of 2?" << std::boolalpha << std::has_single_bit(num) << std::endl;

std::cout << "Leading zeros: " << std::countl_zero(num) << std::endl;

}

八、空指针比较

功能:C++20 引入了新的空指针常量 nullptr 与整数类型的比较操作,明确禁止了这种比较,以防止潜在的逻辑错误。以前,比较 nullptr 和整数在某些实现下是允许的,但现在这样的比较会引发编译错误,确保了代码的清晰和安全。示例(演示非法比较):

void checkPointer(int* ptr) {

// if (ptr == 0) // 在C++20中,这种比较会被认为是错误的。

// std::cout << "ptr is null" << std::endl;

}

九、其他改进和新增特性

关键字和语法增强:引入了 co_await、co_return、co_yield 等关键字以支持协程,consteval 用于声明必须在编译时求值的常量表达式函数,constinit 用于声明必须在编译时初始化的变量,以及 inline 变量等。constexpr 支持的扩展:C++20 扩展了 constexpr 的能力,使其可以用于更复杂的表达式和函数,包括虚函数、动态内存分配、try-catch 异常处理等。std::span:一个轻量级的视图类型,表示一段连续内存的子集,它类似于指针和数组,但更安全、更易用。类型安全和错误检查:通过引入概念(Concepts)和范围(Ranges),C++20 提供了更强的类型安全和更好的编译时错误检查。

总的来说,C++20 的这些新特性和改进使得 C++ 语言更加现代化、强大和易用。

相关推荐