是什么导致了 gcc 中的模糊重载?

2024-05-31

#include <type_traits>
#include <iostream>

template<typename T>
struct Wrapper {
    T value;
    operator T&() & { std::cout << "call const ref" << std::endl; return this->value; }
    operator const T&() const& { std::cout << "call const ref" << std::endl; return this->value; }
    operator T&&() && { std::cout << "call move" << std::endl; return std::move(this->value); }
    operator const T&() const&& = delete;
    operator T&&() & = delete;
    operator T&&() const& = delete;
};

class A {
  public:
        A& operator=(const A&) { std::cout << "use copy" << std::endl; return *this; }
        A& operator=(A&&) { std::cout << "use move" << std::endl; return *this; }
};

int main() {
    Wrapper<A> b;
    A bb;
    bb = std::move(b);
}

我用gcc10.2编译这段代码,并得到以下错误

test.cc: In function ‘int main()’:
test.cc:24:21: error: ambiguous overload for ‘operator=’ (operand types are ‘A’ and ‘std::remove_reference<Wrapper<A>&>::type’ {aka ‘Wrapper<A>’})
   24 |     bb = std::move(b);
      |                     ^
test.cc:17:12: note: candidate: ‘A& A::operator=(const A&)’
   17 |         A& operator=(const A&) { std::cout << "use copy" << std::endl; return *this; }
      |            ^~~~~~~~
test.cc:18:12: note: candidate: ‘A& A::operator=(A&&)’
   18 |         A& operator=(A&&) { std::cout << "use move" << std::endl; return *this; }
      |            ^~~~~~~~

但我在 cppinsights.io 中使用 clang 尝试了相同的代码,并成功编译。

那么,是什么导致了 gcc 和 clang 之间的差异呢? 我该如何改变Wrapper要解决这个问题?

https://godbolt.org/z/37dPqafGK https://godbolt.org/z/37dPqafGK


引用的文本来自 C++20 标准,但链接指向 N4861。

首先让我们最小化给定的代码。如果删除其中三个转换函数,仅留下:,GCC 11.2 和 Clang 12.0.1 的结果如问题中所示(Clang 接受,GCC 拒绝)

operator const T&() const&; // not deleted
operator T&&() &&;          // not deleted
operator const T&() const&& = delete;

由此我们可以推断,Clang 只接受代码,因为在尝试形成隐式转换序列时,该序列将启用A& A::operator=(const A&)被调用时,它选择已删除的Wrapper<A>::operator const T&() const&&执行转换为const A&。因此,形成隐式转换序列fails, and A& A::operator=(const A&)不可行,只剩下另一个候选人了。

GCC 和 Clang 之间的差异似乎与CWG 第 2525 期 https://wg21.link/CWG2525。问题如下:注释1的意图似乎是[over.ics.best.general]/2(N4861 中的[over.ics.best]/2) https://timsong-cpp.github.io/cppwp/n4861/over.best.ics#2.note-1是如果一个隐式转换序列涉及到删除的函数,则仍然认为该隐式转换序列已形成,并且只有需要该隐式转换序列的候选者被选择时,then该程序格式错误,因为它需要调用已删除的函数。但规范性的措辞似乎并没有体现这一意图。

GCC 和 Clang 同意该声明const A& t = std::move(b);格式错误,因为它调用了已删除的函数Wrapper<A>::operator const A&() const&&。因此,Clang 似乎遵循当前存在的规范措辞:因为初始化const A& t = std::move(b)将是格式错误的,因此std::move(b) is 不能隐式转换为 const A& under [conv]/3 https://timsong-cpp.github.io/cppwp/n4861/conv#3,因此使复制赋值运算符成为可行候选者所需的隐式转换序列不存在,并且根据 Clang,只有移动赋值运算符是可行的。但 GCC 正在遵循注释似乎告诉我们的内容:忽略(在重载决策阶段)隐式转换序列之一包含已删除函数的事实。这最终导致GCC无法决定是调用复制赋值运算符还是移动赋值运算符。

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

是什么导致了 gcc 中的模糊重载? 的相关文章

  • 将 Google 云端硬盘访问权限委派给服务帐户失败

    我参与构建了一个内部使用的应用程序 用户可以通过该应用程序上传文件 并将其存储在 Google Drive 中 由于建议不要使用服务帐户作为文件所有者 因此我希望代表公司系统管理员有权访问的指定用户帐户上传应用程序 我已经创建了该应用程序以
  • 信用卡号应该存储为字符串还是整数?

    是啊 只是想想而已 我应该将在我的网站上输入的信用卡号存储为字符串还是整数 我的意思是 它们由数字组成 这让我认为它是一个整数 但我不对它们进行数学运算 所以也许字符串更合适 编辑 所以我必须在加密之前存储在某个时刻输入的数字 我可能应该更
  • 如何使用 lstat() 确定是否为硬链接

    我的操作系统是linux 我用 C 编程 我知道我可以使用 lstat 来识别软链接 即使用 S ISLNK st st mode 但我如何识别该链接是硬链接呢 如果链接是硬链接 它将被视为常规文件 但是 我还想区分常规文件和硬链接 有什么
  • 如何使用仿函数作为类模板中的成员?

    我试图使用函子作为std function类模板内的对象 以下是我到目前为止所做的事情 the functor class template template
  • 在 C 中使用模板函数的最短示例?

    我如何处理函数echo tpl可以采取1类型参数int or string 然后打印出来 C没有模板 我认为你能做的最好的事情就是使用联合或让函数具有不同的名称 后一种具有不同名称的方法是准标准方法 例如fabs fabsf fabsl a
  • 什么是合适的 NHibernate / Iesi.Collections.Generic.ISet 替代品?

    在最新版本的 Iesi Collections 中缺少 Iesi Collections Generic ISet 似乎有三种选择 链接哈希集 只读集 同步集 Iesi Collections Generic ReadOnlySet 似乎最
  • 不同平面中不同幅值的两条线段之间最近的两个 3D 点

    比方说AB1 AB2 CD1 CD2 AB1 AB2 and CD1 CD23D 点构成线段 所说的线段是不在同一平面 AP是一个点 线段AB1 AB2 BP是一个点 线段CD1 CD2 Point1 and Point2彼此最接近 两条线
  • C# 中的 memcpy 函数 [重复]

    这个问题在这里已经有答案了 可能的重复 C memcpy 等效项 https stackoverflow com questions 510971 c memcpy equivalent 相当于什么memcpyC 中的函数 正如已经说过的
  • 处理可选依赖项 (C#)

    我们有一个可以选择与 TFS 集成的应用程序 但是由于集成是可选的 所以我显然不希望所有机器都需要 TFS 程序集作为要求 我应该怎么办 我是否可以在主程序集中引用 TFS 库 并确保在使用 TFS 集成时仅引用 TFS 相关对象 或者 更
  • Unix 编程。不确定如何使用 passwd 结构

    我做了一些研究 但仍在努力解决passwd结构 http www opengroup org onlinepubs 000095399 basedefs pwd h html http www opengroup org onlinepub
  • 如何将值从 ASP.NET MVC 控制器传递到 MVC 视图内的 ASP.NET Webforms 控件?

    我的 ASP NET MVC 方法并未跨越 ASP NET Web 窗体 因此我很难理解如何更好地将值从 ASP NET MVC 控制器传递到 MVC 视图内的 ASP NET Webforms 脚本 例如 控制器动作 public Vie
  • iText7 RegexBasedLocationExtractionStrategy 如何获取找到的文本的字体名和字体大小

    我尝试在 C 上使用 iText7 进行文本替换 我只能使用 RegexBasedLocationExtractionStrategy 获取搜索文本的内容和矩形 并且我想获取文本的字体和大小 有什么建议么 谢谢 你可以实施IText提取策略
  • NHibernate 继承 - 判别器值

    NHibernate 是否可以有一个像这样工作的判别器 如果值等于 String Empty gt Class1 其他 gt Class2 我已经有一个 CultureName 字符串列 我想将其用作鉴别器 我不想添加额外的布尔列 如果 C
  • Linux 相当于 GetCommandLine 和 CommandLineToArgv?

    我想知道是否有一些 API 可以在 Linux 上获取当前进程的命令行参数 我想我是非常不清楚的 该问题的真正目的是通过命令行参数传递 unicode 文件名 从文件中读取 proc self cmdline 例如 wallyk zf od
  • 对双向链表进行排序 C++

    尝试通过遍历列表的循环来完成此操作 在循环中 我将头节点输入到我定义的排序函数中 然后使用 strcmp 来确定节点中的哪个名称是否应该排在前面 它不起作用 因为写得太早了 我通过一次沿着列表一个节点进行线性比较 而不是回去查看第一个节点是
  • 如何在控制台应用程序中创建事件循环/消息管道?

    我想创建一个注册了一些事件的控制台应用程序 问题是这些事件永远不会被触发 在这种特殊情况下Windows 窗体 http en wikipedia org wiki Windows Forms我应该调用的应用程序Application Ru
  • .NET Compact Framework 上的 DateTime.Now 中的毫秒始终为零?

    我想要一个时间戳对于日志Windows 移动项目 精度必须至少在一百毫秒范围内 然而我打电话给DateTime Now返回一个DateTime对象与Millisecond属性设置为零 还有Ticks属性相应地进行四舍五入 如何获得更好的时间
  • Xamarin - iOS 地图上的多个多边形

    我目前正在关注this https developer xamarin com guides xamarin forms application fundamentals custom renderer map polygon map ov
  • 将用户控件绑定到 bool 属性的相反值

    非常简单 我想做同样的事情this https stackoverflow com questions 534575 how do i invert booleantovisibilityconverter但在winforms中 谷歌似乎提
  • 使用 CRTP 模式时继承中的不明确方法

    我正在定义一个DoubleWrapper类继承自两个 CRTP 基类 Ratioable and Divable 两者都定义operator 具有不同的签名 T operator double const scalar const retu

随机推荐

  • 指数数组的边界之外。 (微软.SqlServer.smo)

    我在用SQL Server 2008 R2 它运行良好 但最近 我改变了我的托管服务器 我发现他们已经安装了SQL Server 2012在服务器上 现在 问题是通过连接服务器数据库后SQL Server 2008 R2 当我单击任何表名称
  • 使用 Jackson 删除 JSON 元素

    我有一个特定的 JSON 节点 对应于 import org codehaus jackson JsonNode 而不是 导入 org codehaus jackson map JsonNode givenName Jim formatte
  • 如何将 Ajax 与 jQuery 结合使用

    function ajaxFunction var ajaxRequest The variable that makes Ajax possible try Opera 8 0 Firefox Safari ajaxRequest new
  • Google 地图地点详细信息 API 不返回电话号码

    我正在拨打 地点详细信息 电话 我想取回电话号码 formatted phone number 该字段没有被返回 并且我在响应中没有看到任何电话号码 我将 fields 属性设置为null获取所有可用的属性 const placeDetai
  • HTML Viber 链接到特定号码

    我需要帮助在我的应用程序中实施 Viber 号码 它应该直接使用 Viber 聊天选项连接用户 并且应该在需要发送消息的地方添加特定号码 可以通过 HTML 来做到这一点吗 还有什么其他方法呢 要打开与用户的 Viber 聊天 a href
  • 如何检查字体是否有符号

    我的文档中有以下 css 规则 font family Trebuchet MS Tahoma 但我发现有些浏览器有 Trebuchet MS 字体没有我需要的符号 某些带有非拉丁字符的语言 在这种情况下 浏览器显示方块而不是符号 我怎样才
  • 将 PHP 变量传递给 Jquery 而不刷新

    对于我缺乏 jquery 知识 我预先表示歉意 在我正在构建的这个网站中 向用户展示了许多代表植物的缩略图 单击缩略图时 将启动 jquery 弹出窗口 我希望能够做的是将一个包含植物 ID 的 php 变量传递给 jquery 弹出窗口以
  • Ansible 多个清单文件

    我正在尝试将多个清单文件和动态清单与 Ansible 1 4 和 dev 一起使用 Ansible 返回没有匹配的主机 我有一个模拟场景 目录中有两个主机文件test列出该目录的内容 主机1 ini group1 test1 ansible
  • 如何使用PowerShell脚本远程启动/停止IIS 6.0/7.0?

    我有两台服务器服务器 A 和服务器 B 我想使用 Powershell 脚本从服务器 B 远程停止服务器 A 最简单的方法之一就是使用命令行执行PsExec http www microsoft com technet sysinterna
  • 如何从R中串扰的filter_select中删除(全部)?

    我遵循图 16 7 的示例https plotly r com client side linking html https plotly r com client side linking html并且无法弄清楚为什么有一个名为 全部 的
  • Windows 控制台支持 ANSI 吗?

    Windows 控制台支持 ANSI 控制字符吗 默认情况下它不支持许多 ANSI 控制字符 维基百科文章中也提到了这一点 http en wikipedia org wiki ANSI escape code http en wikipe
  • 如何在C#中使用saveFileDialog保存图像? [复制]

    这个问题在这里已经有答案了 可能的重复 使用 savefiledialog 保存图像时出现问题 https stackoverflow com questions 11053398 issue while saving image usin
  • 以敏捷/BDD 方式在 Django 中使用 Doctests 的示例

    我有兴趣学习如何以更敏捷 BDD 的方式进行文档测试和单元测试 我发现了一些看似合理的教程 但它们只是缩略图 我真正想看到的是一些采用 BDD 风格开发的 Django 项目的源代码 我不清楚的是如何处理请求对象等 我遇到过这样的情况 我已
  • 输入元素有 onload 事件吗?

    当呈现输入元素或任何其他 html 元素时 是否可以触发 Javascript 脚本 该脚本应该从 html 标签内触发 以便我们能够将 this 传递给 js 函数 不 没有这样的事件 然而 一个
  • 有没有使用 Java 访问 Windows COM 方法的方法?

    我有一个应用程序 它利用 JNA 来调用 C 硬件抽象库中的函数 支持的硬件设备之一需要初始化 Windows COM 子系统 通过 CoInitialize 或 CoInitializeEx 有谁知道有什么 Java 库可以做到这一点吗
  • 将一个 div 垂直居中对齐到另一个 div 中

    说我有 div class outer div class inner some stuff div div 内部 div 具有动态高度 它根据 div 内部的内容而变化 外部 div 只是一个容器 设置为具有窗口的高度 我想将其设置为使内
  • PHPUnit 和来自 Guzzle 的模拟请求

    我有一堂具有以下功能的课程 public function get string uri stdClass this gt client new Client response this gt client gt request GET u
  • Typescript / 类型安全柯里化函数

    如何在打字稿中安全地输入柯里化函数 特别注意以下示例 interface Prop
  • 如何使用 xcode 3.1.3 处理 iAd

    目前我正在集成 iAds 并制作该应用程序的精简版 我的问题是以前我使用的 iAds 是 xcode 4 1 3 但目前我使用的是 xcode 3 1 3 iAds 不支持我们所做的 请帮助我 NSString contentSize UI
  • 是什么导致了 gcc 中的模糊重载?

    include