c++中视图是什么意思

在 C++ 中,视图(view)是一种非拥有式的对象,它提供了对其他对象或数据结构的不同方式的读取或处理方式。视图通常是一种轻量级对象,不需要拷贝或分配内存,而是对底层数据结构的一种不同的、特定的、不可变的或只读的视角或访问方式。

在 C++ 标准库中,有多种视图类型,包括 std::spanstd::ranges::viewsstd::string_viewstd::istream_view 等。这些视图类型都提供了一些类似 STL 算法的操作,可以对底层数据进行迭代、筛选、转换、组合等操作,而不需要拷贝或分配内存。

视图在 C++ 中的使用可以帮助简化代码,提高程序的可读性和可维护性,尤其是在处理大量数据的情况下。例如,使用 std::ranges::views 可以轻松地对 STL 容器中的数据进行过滤、映射、排序等操作,而无需创建新的容器或进行内存分配。

需要注意的是,视图是非拥有式的对象,它只提供了对底层数据的一种特定的、不可变的或只读的访问方式,并不拥有底层数据的所有权。因此,在使用视图时需要注意底层数据结构的生命周期和可变性,避免出现不可预料的错误。

c++ 中 std::span 的用法是什么,涵义是什么

std::span 是 C++20 中引入的一种轻量级非拥有式(non-owning)的数组视图类型,它用于表示一个连续的元素序列的范围。具体来说,std::span 表示一个指针和一个元素数量,它不拥有指向这些元素的内存,并且可以在原始数组中移动和指向不同的元素范围。

std::span 的主要作用是允许使用现有的内存(比如 C 风格数组或 std::vector 的底层数组)来创建一个轻量级的视图,而不需要进行内存分配或拷贝。这可以提高程序的性能和效率,特别是在需要处理大量数据的情况下。

使用 std::span 的语法如下:

cppCopy codestd::span<T> s;
std::span<T> s(ptr, count);
std::span<T> s(array);
std::span<T, N> s(array);

其中,T 是元素类型,ptr 是指向元素序列的指针,count 是元素的数量,array 是一个数组(可以是 C 风格数组或 std::array)。

std::span 可以像数组一样进行迭代和访问元素,也可以使用类似 STL 的算法进行处理。例如,以下代码演示了如何使用 std::span 计算数组中所有元素的平均值:

cppCopy code#include <iostream>
#include <span>

int main() {
    int arr[] = {1, 2, 3, 4, 5};
    std::span<int> s(arr);

    double sum = 0;
    for (auto x : s) {
        sum += x;
    }

    std::cout << "Average: " << sum / s.size() << std::endl;
    return 0;
}

std::span 的使用可以帮助简化代码,提高程序的可读性和可维护性,尤其是在涉及到数组操作和算法的情况下。

std::span举几个复杂的例子

std::span 是一个 C++20 中引入的类模板,用于表示一个连续内存区间。它是对裸指针和大小的封装,提供了访问数组的方法和安全性检查。下面是一些复杂的例子:

  1. 拷贝一个 std::vector 的子区间到另一个 std::vector 中:
cppCopy codestd::vector<int> v1{1, 2, 3, 4, 5, 6};
std::vector<int> v2(3);

std::span<int> s1(v1.begin() + 2, v1.begin() + 5);
std::span<int> s2(v2);

s2 = s1; // 拷贝 s1 中的数据到 s2

for (int i : v2) {
    std::cout << i << " "; // 输出:3 4 5
}
  1. 使用 std::span 来实现泛型函数,可以接受不同类型的连续内存区间:
cppCopy codetemplate <typename T>
void print_elements(std::span<T> s) {
    for (auto it = s.begin(); it != s.end(); ++it) {
        std::cout << *it << " ";
    }
    std::cout << std::endl;
}

int main() {
    std::vector<int> v{1, 2, 3, 4, 5};
    int a[] = {6, 7, 8, 9, 10};

    print_elements(v); // 输出:1 2 3 4 5
    print_elements(a); // 输出:6 7 8 9 10
}
  1. 使用 std::span 和算法来实现类似 std::accumulate 的函数:
cppCopy codetemplate <typename T>
T span_sum(std::span<T> s) {
    return std::accumulate(s.begin(), s.end(), T{});
}

int main() {
    std::vector<int> v{1, 2, 3, 4, 5};
    int a[] = {6, 7, 8, 9, 10};

    std::span<int> s1(v);
    std::span<int> s2(a);

    std::cout << span_sum(s1) << std::endl; // 输出:15
    std::cout << span_sum(s2) << std::endl; // 输出:40
}
Logo

助力广东及东莞地区开发者,代码托管、在线学习与竞赛、技术交流与分享、资源共享、职业发展,成为松山湖开发者首选的工作与学习平台

更多推荐