0

0

c++20的std::span和std::string_view有什么核心区别? (所有权与可变性)

尼克

尼克

发布时间:2026-01-11 14:17:20

|

934人浏览过

|

来源于php中文网

原创

std::span是泛型可读写视图,持有原始指针与长度且不管理内存;std::string_view是字符专用只读视图,隐含字符串语义但不保证null结尾,二者类型定位不同导致行为差异。

c++20的std::span和std::string_view有什么核心区别? (所有权与可变性)

std::span 持有原始指针+长度,不管理内存所有权

它只是对已有内存的一层轻量视图,std::span 可以指向数组、堆分配的 std::vector::data(),甚至 C 风格数组,但绝不负责释放——析构时不做任何事。这点和 std::string_view 一致,但适用范围更广。

常见误用:std::span make_span() { char buf[10] = {}; return std::span{buf}; } —— 返回后 buf 被销毁,span 指向悬垂内存。

std::string_view 专用于字符序列,隐含 null-termination 语义但不依赖它

std::string_view 的底层是 const char* + size_t,只接受字符类型(charchar8_t 等),且设计初衷是替代 const std::string& 做只读字符串参数传递。它不保证数据以 \0 结尾,但多数成员函数(如 data())返回的指针可安全传给 C 接口——前提是调用者确保内容合法。

关键限制:std::string_view 不能持有 std::vectordata() 并自动推导长度(除非显式传入 .size()),而 std::span 对任意连续容器都支持构造:

立即学习C++免费学习笔记(深入)”;

std::vector v = {'h', 'e', 'l', 'l', 'o'};
std::span s1{v};                    // OK,自动推导为 span
std::string_view sv{v.data(), v.size()}; // 必须手动传 size,否则编译失败

可变性:std::span 支持非常量元素访问,std::string_view 固定只读

std::span 中的 T 可以是非 const 类型,因此能修改所指内存:

Short AI
Short AI

AI短视频生成器,轻松创作爆款短视频!

下载
int arr[] = {1, 2, 3};
std::span s{arr};
s[0] = 42; // 合法:修改 arr[0]

std::string_view 的模板参数固定为 const CharT*,没有非 const 版本。即使你写 std::string_view,实际仍是 const char* 底层——C++20 标准明确禁止提供可变字符视图,避免与 std::string 职责混淆。

注意:这不是“设计疏漏”,而是有意为之。若需可变字符操作,请用 std::span 或直接操作原容器。

类型安全与隐式转换陷阱

std::string_view 允许从 const char* 隐式构造(只要带长度或含 \0),但 std::span 对隐式转换极其克制:

  • std::string_view{"hello"} → OK(字面量推导为 const char[6]
  • std::span{arr} → OK(数组退化为指针+推导长度)
  • std::span{ptr}(仅指针)→ 编译失败:必须显式指定长度或使用容器
  • std::span{std::vector{1,2,3}} → OK(完美转发容器)

最易踩坑的是把 std::string_view 当通用视图用:它无法表示 std::vectorstd::array 等非字符类型——这时候必须换 std::span

核心差异其实就两点:一个是「字符专用只读视图」,一个是「泛型可读写视图」;所有行为差异都从这个根本定位里长出来。别试图让 string_viewspan 的事,也别用 span 替代 string_view 去接 API 要求字符串语义的地方——类型系统在这儿是有真实约束力的。

相关专题

更多
string转int
string转int

在编程中,我们经常会遇到需要将字符串(str)转换为整数(int)的情况。这可能是因为我们需要对字符串进行数值计算,或者需要将用户输入的字符串转换为整数进行处理。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

315

2023.08.02

css中float用法
css中float用法

css中float属性允许元素脱离文档流并沿其父元素边缘排列,用于创建并排列、对齐文本图像、浮动菜单边栏和重叠元素。想了解更多float的相关内容,可以阅读本专题下面的文章。

556

2024.04.28

C++中int、float和double的区别
C++中int、float和double的区别

本专题整合了c++中int和double的区别,阅读专题下面的文章了解更多详细内容。

98

2025.10.23

c语言中null和NULL的区别
c语言中null和NULL的区别

c语言中null和NULL的区别是:null是C语言中的一个宏定义,通常用来表示一个空指针,可以用于初始化指针变量,或者在条件语句中判断指针是否为空;NULL是C语言中的一个预定义常量,通常用来表示一个空值,用于表示一个空的指针、空的指针数组或者空的结构体指针。

231

2023.09.22

java中null的用法
java中null的用法

在Java中,null表示一个引用类型的变量不指向任何对象。可以将null赋值给任何引用类型的变量,包括类、接口、数组、字符串等。想了解更多null的相关内容,可以阅读本专题下面的文章。

435

2024.03.01

java基础知识汇总
java基础知识汇总

java基础知识有Java的历史和特点、Java的开发环境、Java的基本数据类型、变量和常量、运算符和表达式、控制语句、数组和字符串等等知识点。想要知道更多关于java基础知识的朋友,请阅读本专题下面的的有关文章,欢迎大家来php中文网学习。

1463

2023.10.24

c语言const用法
c语言const用法

const是关键字,可以用于声明常量、函数参数中的const修饰符、const修饰函数返回值、const修饰指针。详细介绍:1、声明常量,const关键字可用于声明常量,常量的值在程序运行期间不可修改,常量可以是基本数据类型,如整数、浮点数、字符等,也可是自定义的数据类型;2、函数参数中的const修饰符,const关键字可用于函数的参数中,表示该参数在函数内部不可修改等等。

520

2023.09.20

js 字符串转数组
js 字符串转数组

js字符串转数组的方法:1、使用“split()”方法;2、使用“Array.from()”方法;3、使用for循环遍历;4、使用“Array.split()”方法。本专题为大家提供js字符串转数组的相关的文章、下载、课程内容,供大家免费下载体验。

253

2023.08.03

c++主流开发框架汇总
c++主流开发框架汇总

本专题整合了c++开发框架推荐,阅读专题下面的文章了解更多详细内容。

78

2026.01.09

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
国外Web开发全栈课程全集
国外Web开发全栈课程全集

共12课时 | 1.0万人学习

进程与SOCKET
进程与SOCKET

共6课时 | 0.3万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号