0Pricing
C++ Academy · 课时

向函数传递 Span

编写灵活的 API

向函数传递 Span 是 CoddyKit 上的免费 C++ Academy 课时。 这是第 3 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 C++ Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 C++ Academy 课程共包含 4 节课。

一个函数适用于多种容器

接收 std::span 的函数可以同样接受数组、向量和原始缓冲区,无需模板或重载。

#include <iostream>
#include <span>
#include <vector>
#include <array>
int sum(std::span<const int> s) {
    int t = 0; for (int x : s) t += x; return t;
}
int main() {
    std::vector<int> v = {1, 2, 3};
    std::array<int, 2> a = {4, 5};
    std::cout << sum(v) << " " << sum(a) << "\n";
}

无需大小参数

旧式 C 风格接口会传递一个指针和一个单独的大小。span 将二者捆绑在一起,消除了长度不匹配导致的错误。

#include <iostream>
#include <span>
void printAll(std::span<const int> s) {
    for (int x : s) std::cout << x << " ";
    std::cout << "\n";
}
int main() {
    int buf[] = {7, 8, 9};
    printAll(buf); // size inferred
}

用于只读的 const span

使用 std::span<const T> 可以声明该函数不会修改调用方的数据。

#include <iostream>
#include <span>
int maxOf(std::span<const int> s) {
    int m = s[0];
    for (int x : s) if (x > m) m = x;
    return m;
}
int main() {
    int data[] = {3, 9, 4};
    std::cout << maxOf(data) << "\n"; // 9
}

用于原地编辑的可变 span

非 const span 允许函数直接修改调用方的元素。

#include <iostream>
#include <span>
#include <vector>
void doubleAll(std::span<int> s) {
    for (int& x : s) x *= 2;
}
int main() {
    std::vector<int> v = {1, 2, 3};
    doubleAll(v);
    std::cout << v[2] << "\n"; // 6
}

避免模板膨胀

没有 span 时,可能需要针对容器类型使用模板,从而生成许多实例。span 提供一个具体的函数签名即可直接工作。

避免复制

传递 span 从不复制元素,只有指针和长度会传入函数。

#include <iostream>
#include <span>
#include <vector>
size_t count(std::span<const int> s) { return s.size(); }
int main() {
    std::vector<int> big(1000, 0);
    std::cout << count(big) << "\n"; // no copy of 1000 ints
}

空 Span 也没有问题

函数应妥善处理空 span;size() 为零,基于范围的循环也只会执行零次。

#include <iostream>
#include <span>
int sum(std::span<const int> s) { int t = 0; for (int x : s) t += x; return t; }
int main() {
    std::span<const int> empty;
    std::cout << sum(empty) << "\n"; // 0
}

按值传递

Span 很小,因此请按值传递,而不是按引用传递。复制一个指针和长度几乎没有开销。

明确记录 const 意图

选择 span<const T> 还是 span<T>,调用方一眼就能看出其数据是否可能被修改。

调用方保留所有权

容器的所有权仍归调用方;span 只在调用期间借用容器。函数不得在调用结束后继续保存该 span。

现代 API 风格

接受 span 是为连续数据编写函数的惯用现代方式,灵活、安全且无需复制。

快速检查

检查您对传递 span 的理解。

回顾

您学习了如何向函数传递 span:

  • 一个签名即可接受数组、向量和缓冲区。
  • 使用 span<const T> 实现只读;使用 span<T> 进行原地编辑。
  • 按值传递,不会复制任何内容。
  • 调用方保留所有权;调用结束后不要保存 span。

常见问题解答

「向函数传递 Span」课时是免费的吗?

是的 — 「向函数传递 Span」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 C++ Academy 课程的其余内容,请升级到 CoddyKit PRO。 C++ Academy 课程共包含 4 节课。

「向函数传递 Span」这节课中我会学到什么?

编写灵活的 API 你通过在浏览器中直接运行的动手代码来练习 C++ Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。

学习 C++ Academy 需要有经验吗?

无需任何先前经验。CoddyKit 上的 C++ Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 3 节课,共 4 节。

「向函数传递 Span」课时需要多长时间?

大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。

我能在这节 C++ Academy 课中编写并运行代码吗?

能。每节 C++ Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。

此课程中的所有课时

  1. 定长 std::array
  2. std::span 基础
  3. 向函数传递 Span
  4. 边界与子 Span
← 返回 C++ Academy