为什么 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 在三元表达式中创建悬挂视图? 的相关文章

  • 没有强命名的代码签名是否会让您的应用程序容易被滥用?

    尝试了解authenticode代码签名和强命名 我是否正确地认为 如果我对引用一些 dll 非强命名 的 exe 进行代码签名 恶意用户就可以替换我的 DLL 并以看似由我签名但正在运行的方式分发应用程序他们的代码 假设这是真的 那么您似
  • “构建”构建我的项目,“构建解决方案”则不构建

    我刚刚开始使用VS2010 我有一个较大的解决方案 已从 VS2008 成功迁移 我已将一个名为 Test 的控制台应用程序项目添加到解决方案中 选择构建 gt 构建解决方案不编译新项目 选择构建 gt 构建测试确实构建了项目 在失败的情况
  • 动态加载程序集的应用程序配置

    我正在尝试将模块动态加载到我的应用程序中 但我想为每个模块指定单独的 app config 文件 假设我的主应用程序有以下 app config 设置
  • 秒表有最长运行时间吗?

    多久可以Stopwatch在 NET 中运行 如果达到该限制 它会回绕到负数还是从 0 重新开始 Stopwatch Elapsed返回一个TimeSpan From MSDN https learn microsoft com en us
  • C#中如何移动PictureBox?

    我已经使用此代码来移动图片框pictureBox MouseMove event pictureBox Location new System Drawing Point e Location 但是当我尝试执行时 图片框闪烁并且无法识别确切
  • WCF 中 SOAP 消息的数字签名

    我在 4 0 中有一个 WCF 服务 我需要向 SOAP 响应添加数字签名 我不太确定实际上应该如何完成 我相信响应应该类似于下面的链接中显示的内容 https spaces internet2 edu display ISWG Signe
  • 显示UnityWebRequest的进度

    我正在尝试使用下载 assetbundle统一网络请求 https docs unity3d com ScriptReference Networking UnityWebRequest GetAssetBundle html并显示进度 根
  • 使用 Bearer Token 访问 IdentityServer4 上受保护的 API

    我试图寻找此问题的解决方案 但尚未找到正确的搜索文本 我的问题是 如何配置我的 IdentityServer 以便它也可以接受 授权带有 BearerTokens 的 Api 请求 我已经配置并运行了 IdentityServer4 我还在
  • 转发声明和包含

    在使用库时 无论是我自己的还是外部的 都有很多带有前向声明的类 根据情况 相同的类也包含在内 当我使用某个类时 我需要知道该类使用的某些对象是前向声明的还是 include d 原因是我想知道是否应该包含两个标题还是只包含一个标题 现在我知
  • 如何在 C 中调用采用匿名结构的函数?

    如何在 C 中调用采用匿名结构的函数 比如这个函数 void func struct int x p printf i n p x 当提供原型的函数声明在范围内时 调用该函数的参数必须具有与原型中声明的类型兼容的类型 其中 兼容 具有标准定
  • 如何查看网络连接状态是否发生变化?

    我正在编写一个应用程序 用于检查计算机是否连接到某个特定网络 并为我们的用户带来一些魔力 该应用程序将在后台运行并执行检查是否用户请求 托盘中的菜单 我还希望应用程序能够自动检查用户是否从有线更改为无线 或者断开连接并连接到新网络 并执行魔
  • Windows 窗体:如果文本太长,请添加新行到标签

    我正在使用 C 有时 从网络服务返回的文本 我在标签中显示 太长 并且会在表单边缘被截断 如果标签不适合表单 是否有一种简单的方法可以在标签中添加换行符 Thanks 如果您将标签设置为autosize 它会随着您输入的任何文本自动增长 为
  • 覆盖子类中的字段或属性

    我有一个抽象基类 我想声明一个字段或属性 该字段或属性在从该父类继承的每个类中具有不同的值 我想在基类中定义它 以便我可以在基类方法中引用它 例如覆盖 ToString 来表示 此对象的类型为 property field 我有三种方法可以
  • 链接器错误:已定义

    我尝试在 Microsoft Visual Studio 2012 中编译我的 Visual C 项目 使用 MFC 但出现以下错误 error LNK2005 void cdecl operator new unsigned int 2
  • 如何从两个不同的项目中获取文件夹的相对路径

    我有两个项目和一个共享库 用于从此文件夹加载图像 C MainProject Project1 Images 项目1的文件夹 C MainProject Project1 Files Bin x86 Debug 其中有project1 ex
  • 为什么编译时浮点计算可能不会得到与运行时计算相同的结果?

    In the speaker mentioned Compile time floating point calculations might not have the same results as runtime calculation
  • 通过指向其基址的指针删除 POD 对象是否安全?

    事实上 我正在考虑那些微不足道的可破坏物体 而不仅仅是POD http en wikipedia org wiki Plain old data structure 我不确定 POD 是否可以有基类 当我读到这个解释时is triviall
  • 将控制台重定向到 .NET 程序中的字符串

    如何重定向写入控制台的任何内容以写入字符串 对于您自己的流程 Console SetOut http msdn microsoft com en us library system console setout aspx并将其重定向到构建在
  • C# 模拟VolumeMute按下

    我得到以下代码来模拟音量静音按键 DllImport coredll dll SetLastError true static extern void keybd event byte bVk byte bScan int dwFlags
  • C# - OutOfMemoryException 在 JSON 文件上保存列表

    我正在尝试保存压力图的流数据 基本上我有一个压力矩阵定义为 double pressureMatrix new double e Data GetLength 0 e Data GetLength 1 基本上 我得到了其中之一pressur

随机推荐

  • 如何将列表从控制器传递到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