为什么 std::string_view 在三元表达式中创建悬挂视图?

2024-04-12

考虑一个返回 a 的方法std::string_view要么来自返回 a 的方法const std::string&或来自空字符串。令我惊讶的是,以这种方式编写方法会导致悬空字符串视图:

const std::string& otherMethod();

std::string_view myMethod(bool bla) {
    return bla ? otherMethod() : ""; // Dangling view!
}

https://godbolt.org/z/1Hu_p2 https://godbolt.org/z/1Hu_p2

看来编译器首先放置了一个临时的std::string结果的副本otherMethod()放在堆栈上,然后返回此临时副本的视图,而不仅仅是返回引用的视图。首先我想到了编译器错误,但 G++ 和 clang 都会这样做。

修复方法很简单:包裹otherMethod转化为显式构造string_view解决问题:

std::string_view myMethod(bool bla) {
    return bla ? std::string_view(otherMethod()) : ""; // Works as intended!
}

https://godbolt.org/z/Q-sEkr https://godbolt.org/z/Q-sEkr

为什么会这样呢?为什么原始代码会在没有警告的情况下创建隐式副本?


因为这就是条件运算符的工作原理。

你正在调用?:在两个操作数上,其中之一是类型的左值std::string const另一个是类型的左值char const[1]。条件运算符的语言规则......非常复杂。这相关规则 http://eel.is/c++draft/expr.cond#4 is:

否则,如果第二个和第三个操作数具有不同的类型并且其中一个具有(可能是 cv 限定的)类类型,或者如果两者都是相同值类别和相同类型的泛左值(除了cv- 限定,尝试形成从每个操作数到另一个操作数的类型的隐式转换序列。 [Note:对于该确定,将忽略诸如访问、操作数是否为位字段或是否删除转换函数之类的属性。 — 尾注 ]尝试从操作数表达式形成隐式转换序列E1类型的T1与该类型相关的目标类型T2操作数表达式的E2如下:

  • 如果 E2 是左值,则目标类型是“对的左值引用”T2”,但受到以下约束:在转换中,引用必须直接绑定 ([dcl.init.ref]) 到左值。
  • 如果 E2 是 x 值,[...]
  • 如果 E2 是纯右值或者如果上面的转换序列都不能形成,并且至少一个操作数具有(可能是 cv 限定的)类类型:

    • if T1 and T2是相同的班级类型 [...]
    • 否则,如果T2是一个基类T1, [...]
    • 否则,目标类型是 E2 在应用左值到右值、数组到指针和函数到指针标准转换后将具有的类型。

使用该过程,确定是否可以形成从第二操作数到为第三操作数确定的目标类型的隐式转换序列,反之亦然。如果两个序列都可以形成,或者可以形成一个序列但它是不明确的转换序列,则该程序是错误的。如果无法形成转换序列,则操作数保持不变,并按如下所述执行进一步检查。否则,如果可以形成恰好一个转换序列,则将该转换应用于所选操作数,并且对于本子条款的其余部分,使用转换后的操作数代替原始操作数。 [Note:即使可以形成隐式转换序列,转换也可能是格式错误的。 —end note ]

无法转换std::string const到任一char const(&)[1] or char const*, 但是你可以转换 char const[1] to std::string const(内部嵌套项目符号)...这就是你得到的。类型的纯右值std::string const。也就是说,您要么复制一个字符串,要么构造一个新字符串......无论哪种方式,您都会返回一个string_view到立即超出范围的临时对象。


您想要的就是您拥有的:

std::string_view myMethod(bool bla) {
    return bla ? std::string_view(otherMethod()) : "";
}

or:

std::string_view myMethod(bool bla) {
    return bla ? otherMethod() : ""sv;
}

该条件运算符的结果是string_view,这两种转换都是安全的。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

为什么 std::string_view 在三元表达式中创建悬挂视图? 的相关文章

  • 在 C# 中使用“using”关键字避免多次处置的最佳实践

    当变量是 IDisposable 时 我们有using关键字来管理处置 但是如果我们在方法中返回值怎么办 using twice StringContent stringToStringContent string str using St
  • 是否可以从 C++ 应用程序调用 C# 应用程序?

    我是一名编程学生 现在我已经上了两门 C 课程 这个学期我将参加我的第一门 C 课程 出于好奇 是否可以从 C 应用程序调用 C 应用程序 如果是的话 是否还可以检查运行该程序的计算机是否具有 NET框架 我只是很好奇 我想如果可能的话 这
  • 如果 JSON.NET 中的值为 null 或空格,则防止序列化

    我有一个对象需要以这样的方式序列化 即 null 和 空白 空或只是空格 值都不会序列化 我不控制对象本身 因此无法设置属性 但我知道所有属性都是字符串 环境NullValueHandling显然 忽略 只能让我找到解决方案的一部分 它 似
  • 将 OpenCV Mat 转换为数组(可能是 NSArray)

    我的 C C 技能很生疏 OpenCV 的文档也相当晦涩难懂 有没有办法获得cv Mat data属性转换为数组 NSArray 我想将其序列化为 JSON 我知道我可以使用 FileStorage 实用程序转换为 YAML XML 但这不
  • 司机和提供商之间的区别

    数据库中的驱动程序和提供程序有什么区别 有没有解释一下 不胜感激 样本 ADO NET driver for MySQL vs providerName System Data EntityClient 来自 MSDN 论坛 驱动程序是安装
  • 将设置函数(setter)标记为 constexpr 的目的是什么? [复制]

    这个问题在这里已经有答案了 我无法理解将 setter 函数标记为的目的constexpr 自 C 14 起这是允许的 我的误解来自以下情况 我使用 constexpr c tor 声明一个类 并且我将通过创建该类的 constexpr 实
  • 将下拉列表与字典绑定

    我将字典绑定到下拉列表 举例来说 我的字典中有以下项目 Test1 123 Test2 321 我希望下拉文本采用以下格式 Test1 Count 123 Test2 Count 321 我沿着以下路径走 但没有运气 MyDropDown
  • 将日期时间转换为指定格式

    我有这个日期格式yy MM dd HH mm ss ex 12 02 21 10 56 09 问题是 当我尝试使用以下代码将其转换为不同格式时 CDate 12 02 21 10 56 09 ToString MMM dd yyyy HH
  • 使用 C# 中的 Google 地图 API 和 SSIS 包获取行驶距离

    更新 找到了谷歌距离矩阵并尝试相应地修改我的代码 我在这里收到无效参数错误 return new GeoLocation dstnc uri ToString catch return new GeoLocation 0 0 https 基
  • 如何在 C# 中获取 Json 数组?

    我有一个像这样的 Json 字符串 我想将它加载到 C 数组中 当我尝试这样做时 我收到异常 我的字符串 customerInformation customerId 123 CustomerName Age 39 Gender Male
  • ALTER TABLE ... ADD CONSTRAINT 失败时将事务回滚到保存点

    有没有办法在事务中添加检查约束and如果失败回滚到以前的保存点 而不是回滚整个事务 就我而言 当 ALTER TABLE ADD CONSTRAINT 命令失败时 事务无法回滚到保存点 尝试这样做会引发 InvalidOperationEx
  • C# 中的 C/C++ 代码编译器

    在 C 中 我可以使用下面的代码编译 VB 和 C 代码 但无法编译 C C 代码 有什么办法可以做到这一点吗 C 编译器 public void Compile string ToCompile string Result null st
  • 为什么 f(i = -1, i = -1) 是未定义的行为?

    我正在读关于违反评估顺序 http en cppreference com w cpp language eval order 他们举了一个令我困惑的例子 1 如果标量对象上的副作用相对于同一标量对象上的另一个副作用是无序的 则行为未定义
  • C 中使用 getrandom 实现随机浮点数

    我试图生成一个介于 0 和 1 之间的随机浮点数 无论是在 0 1 还是 0 1 对我来说都不重要 网上关于此的每个问题似乎都涉及rand 呼叫 播种time NULL 但我希望能够每秒多次调用我的程序 并每次都获得不同的随机数 这引导我找
  • 浮点字节序?

    我正在为实时海上模拟器编写客户端和服务器 并且由于我必须通过套接字发送大量数据 因此我使用二进制数据来最大化可以发送的数据量 我已经了解整数字节顺序以及如何使用htonl and ntohl为了规避字节顺序问题 但我的应用程序与几乎所有模拟
  • 在哪里可以下载没有 Visual Studio 2010 的 C# 4.0 编译器?

    我知道 CTP VS 2010 映像 但我可以只下载 NET Framework 4 0 和 C 编译器吗 AFAIK VS 2010 CTP 仅作为 VM 映像提供 我不相信 Microsoft 发布了 VS 的安装程序 其中一个绝对不适
  • Linq.Select() 中的嵌套表达式方法调用

    I use Select i gt new T 每次手动点击数据库后将我的实体对象转换为 DTO 对象 以下是一些示例实体和 DTOS 用户实体 public partial class User public int Id get set
  • Xamarin.Forms UWP 项目中标题栏和选项卡之间令人恼火的空白

    我几乎是新手Xamarin Forms我正在开发一个相当简单的跨平台应用程序 该应用程序在 Android 中显示得足够好 但在 UWP 中却出现了一个愚蠢的空白 该项目由一个 TabbedPage 组成 其中包含 4 个 Navigati
  • 有没有办法直接在函数参数中格式化字符串而不是使用临时字符串?

    我有一个接受字符串 字符数组 作为参数的函数 void enterString char my string 当使用这个函数时 我经常发现自己想要输入格式化的字符串 我使用 sprintf 来做到这一点 然而 我每次都必须创建一个临时字符串
  • 为什么表达式 a = a + b - ( b = a ) 在 C++ 中给出序列点警告?

    以下是测试代码 int main int a 3 int b 4 a a b b a cout lt lt a lt lt a lt lt lt lt b lt lt b lt lt n return 0 编译此命令会出现以下警告 gt g

随机推荐

  • 如何将列表从控制器传递到asp.net mvc中的javascript函数?

    我在控制器中有这个查询 DataClasses1DataContext behzad new DataClasses1DataContext var query from p in behzad ImagePaths select new
  • Jekyll 无法服务(Ruby 不兼容的库版本)

    当尝试跑步时jekyll serve 它似乎构建正确 尽管有我无法解决的警告 但随后无法提供服务 jekyll build完成 但生成的文件缺少已编译的 CSS 输出来自jekyll serve Ignoring ffi 1 9 10 be
  • PetaPoco 处理枚举吗?

    我正在尝试使用 PetaPoco 将表转换为 POCO 在我的表中 有一列名为TheEnum 此列中的值是表示以下枚举的字符串 public enum MyEnum Fred Wilma 当 PetaPoco 试图将字符串 Fred 转换为
  • 如何快速打印数组中对象的值,而不是其位置

    我有一个类 其中包含同一项目中单独的 swift 文件中某些企业家的数据 它看起来像这样 class Entrepreneur NSObject var name String var netWorth 0 0 var company St
  • 如何在不改变编码风格的情况下避免空白锚下划线?

    看看下面的小提琴 http jsfiddle net DNhAk 14 http jsfiddle net DNhAk 14 当您的图像的文本包含在锚点 链接中时 代码中图像和文本之间的空白会在呈现的页面中的文本之前创建一个带下划线的空白
  • RIFF/Wav 标头中的“LIST”块是什么?

    我正在编写一个 wav 播放器 并且使用以下文件格式规范 http soundfile sapp org doc WaveFormat http soundfile sapp org doc WaveFormat 正如您所看到的 它期望 一
  • 返回类型的具体类型或接口?

    今天我遇到了对象编程风格 具体类型或接口的一个基本悖论 对于方法的返回类型 哪个更好 具体类型还是接口 在大多数情况下 我倾向于使用具体类型作为方法的返回类型 因为我相信具体类型对于进一步使用更加灵活并且公开更多功能 其阴暗面 耦合 天使般
  • 使用窗口 ID 激活窗口

    我将如何以编程方式激活 即移动到前面并聚焦 macOS 上的窗口 不属于我的应用程序 Window ID 我的应用程序将在用户授予辅助权限等的情况下运行 令人惊讶的是 上面没有描述任何功能石英窗服务页面 https developer ap
  • 如何在每个页面上多次使用具有相同类名的 Masonry?

    我需要每页有多个砌体网格 我使用 wordpress 循环生成代码 因此每个 div 容器都具有相同的类名 有没有办法在所有同名的 div 容器上调用 Masonry html div class print slider div clas
  • PHP:三元运算符

    这似乎是一个非常简单的问题 但我尝试的一切都给了我一个错误 if query results gt have posts count results query results gt found posts 问题 如何添加else这段代码的
  • Erlang停止gen_server

    我有 gen server start UserName gt case gen server start global UserName player of ok gt io format Player UserName started
  • 为什么我的 img 错误函数失败?

    我动态构建的一些 img 元素可能会失败 对于这些情况 我从这里得到了一些代码 有没有办法以编程方式确定图像链接是错误的 https stackoverflow com questions 17702123 is there a way t
  • PHP:类似 Youtube 的短 ID,带有盐

    我需要对数据库 ID 进行编码 加密并将其附加到我的 URL 中 安全性不是我想要解决的问题 但我正在寻找具有中等安全性的东西 主要目标是拥有唯一且 URL 安全的短 ID 下面的代码片段似乎可以满足我的需要 来自http programa
  • 推送通知未显示

    我开发了一个使用推送插件的phonegap应用程序 我创建了一个示例服务器 推送消息未显示在通知栏中 但消息正在应用程序中显示 请帮忙 我的代码是 var 推送通知 function onDeviceReady app status ul
  • 为什么这个 Parallel.ForEach 代码会冻结程序?

    更多新手问题 此代码从主窗口的列表中获取多个代理 我不知道如何使变量在不同函数之间可用 并对每个代理进行检查 简单httpwebrequest 然后将它们添加到名为的列表中finishedProxies 由于某种原因 当我按下开始按钮时 整
  • 如何在 linq 中对引用类型属性进行分组?

    我有一堂这样的课 public class Order public int Id public Person SalesPerson public class Person public int Id public string Name
  • 我在哪里可以找到 jpa orm.xml 使用示例[关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 我正在尝试查看 JPA orm xml 的一些使用示例 如果有人引导我访问链接 架构在这里 http java sun com xml n
  • 类变量、成员变量、局部变量、全局变量之间的区别[关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 类变量 成员变量 局部变量和全局变量的分类 在类定义中定义为 static 的变量是类变量 public MyClass static
  • 如何通过 pip 安装 twilio 软件包?

    I have Python 2 7 12 64 位 安装在我的 Windows 计算机上 我安装的时候添加了pip和执行程序小路 现在当我尝试安装时Twilio with pip install twilio 我收到错误 pip is no
  • 为什么 std::string_view 在三元表达式中创建悬挂视图?

    考虑一个返回 a 的方法std string view要么来自返回 a 的方法const std string 或来自空字符串 令我惊讶的是 以这种方式编写方法会导致悬空字符串视图 const std string otherMethod