给定以下代码(在 GCC 4.3 中),为什么调用转换为引用两次?

2024-06-05

给定以下代码(在 GCC 4.3 中),为什么在这两种情况下都会调用到引用的转换?

class A { };

class B {
public:
  operator A() {}
  operator A&() {}
};

int main() {
  B b;
  (A) b;
  (A&) b;
}

http://ideone.com/d6iF8 http://ideone.com/d6iF8


您的代码不明确,不应编译(它是不规范的每 13.3.3:2)。

左值到右值转换与恒等转换具有相同的等级,因此(根据 13.3.3:1)无法在它们之间进行选择。

科莫 C++ http://www.comeaucomputing.com/tryitout(可能是最符合标准的编译器)给出以下错误:

"ComeauTest.c", line 11: error: more than one user-defined conversion from "B" to
          "A" applies:
            function "B::operator A()"
            function "B::operator A &()"
    (A) b;
        ^

以下是该标准的相关文本:

c++11 /questions/tagged/c%2b%2b11

13.3.3 最佳可行函数[over.match.best]

[...]给定这些定义,一个可行函数 F1 被定义为比另一个可行函数 F2 更好的函数 [...]

2 - 如果恰好有一个可行函数比所有其他可行函数都更好,那么它就是 由重载决议选择的一个;否则调用的格式不正确。

定义本身很复杂,但用户定义的转换有两点需要注意:

一、应用用户自定义转换作为转换序列指定分解为序列S_a - U - S_b一个标准转换序列,后跟一个用户定义的转换,然后是另一个标准转换序列。这涵盖了所有情况;在一个转换序列中不能有多个用户定义的转换,并且标准转换序列可以是“身份转换”,即不需要转换。

其次,在比较用户定义的转换序列时,唯一重要的部分是第二个标准转换序列。这是在 13.3.3 中:

c++11 /questions/tagged/c%2b%2b11

13.3.3 最佳可行函数[over.match.best]

[...] 可行函数 F1 被定义为比另一个可行函数更好的函数 F2 如果 [...]

  • 上下文是通过用户定义的转换进行的初始化(参见 8.5、13.3.1.5 和 13.3.1.6) 从 F1 的返回类型到目标类型(即 正在初始化的实体)是比标准转换序列更好的转换序列 F2 到目标类型的返回类型。

以及 13.3.3.2 中:

c++11 /questions/tagged/c%2b%2b11

13.3.3.2 对隐式转换序列进行排序 [over.ics.rank]

3 - 两个相同形式的隐式转换序列是无法区分的转换序列,除非其中之一 以下规则适用:[...]

  • 如果用户定义的转换序列 U1 包含相同的用户定义的转换函数或构造函数或聚合,则它们是比另一个用户定义的转换序列 U2 更好的转换序列 U1的初始化和第二标准转换序列优于第二标准 U2的转换序列。

所以在比较转换序列时U1 = (S1_a - U'1 - S1_b) and U2 = (S2_a - U'2 - S2_b)唯一重要的是相对排名S1_b and S2_b;达到用户定义的转换参数所需的标准转换序列并不重要。

所以可能的转换顺序为(A) b,需要一个转换序列产生B -> A, are:

U1: B -> B [identity], B::operator A() [user-defined], A -> A [identity]
U2: B -> B [identity], B::operator A &() [user-defined], A & -> A [rvalue-to-lvalue]

现在,我们如何对标准转换序列进行排序?需要查看的地方是 13.3.3.1.1 中的表 12,它指定左值到右值转换与恒等转换具有相同的等级(“精确匹配”)。因此无法区分两个用户定义的转换序列,并且程序是格式错误的。


Sidebar

在对用户定义的转换序列进行排序方面,13.3.3 和 13.3.3.2 有什么区别?

13.3.3 允许编译器区分不同的用户定义的转换运算符; 13.3.3.2 允许编译器区分不同的功能每个都需要在其参数中进行用户定义的转换。

所以,在代码中

struct A {
    operator int();
    operator float();
} a;
void f(int);
f(a);

13.3.3 适用并且A::operator int()被选择超过A::operator float();在代码中

struct A {
    operator int();
} a;
void f(int);
void f(double);
f(a);

13.3.3.2 适用并且void f(int)被选择超过void f(double)。然而在代码中

struct A {
    operator int();
    operator float();
} a;
void f(int);
void f(double);
f(a);

尽管 13.3.3 更喜欢A::operator int() -> void f(int) over A::operator float() -> void f(int) and float -> double over int -> double,并且 13.3.3.2 更喜欢int -> int over int -> double and float -> double over float -> int,没有办法区分int -> int and float -> double转换序列(因为它们既不包含相同的用户定义转换运算符,也不包含相同的重载f),因此代码格式不正确。

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

给定以下代码(在 GCC 4.3 中),为什么调用转换为引用两次? 的相关文章

  • Taglib:性能和崩溃问题

    我在 Qt 应用程序中使用 taglib 库 1 7 2 从音乐文件夹中读取 mp3 文件的一些元数据 问题是我发现它非常慢 例如 这是代码 QString path C Music QDir d path QStringList file
  • 如何调试Roslyn编译生成的dll?

    我正在使用 Roslyn CSharpCompilation 为我的插件生成 dll 文件 文件具有 OptimizationLevel Debug 并生成 pdb 文件 接下来 我使用 Assembly Load 将这些文件加载 到我的程
  • 我们可以在 C# 中定义枚举的隐式转换吗?

    是否可以在 C 中定义枚举的隐式转换 可以实现这一目标的东西吗 public enum MyEnum one 1 two 2 MyEnum number MyEnum one long i number 如果没有 为什么不呢 有一个解决方案
  • 求 a 范围内的 pow(a^b)modN

    对于给定的b and N以及一系列a say 0 n 我需要找到ans 0 n 1 where ans i 没有a s为此pow a b modN i 我在这里搜索的是可能的重复pow a b modN对于一系列a 以减少计算时间 例子 i
  • gets 和 scanf 有什么区别?

    如果代码是 scanf s n message vs gets message 有什么区别 似乎两者都获取消息的输入 基本区别 参考您的特定场景 scanf 遇到一个时结束接受输入whitespace newline or EOF gets
  • 在 2 个 .c 文件之间共享函数

    dir1有dir2 file1 c和file1 h dir2 有 file2 c 现在 如果我想在 file2 c 中访问 file1 c 中定义的函数 我需要在 file1 h 中声明它并在 file2 c 中包含 file1 h 这是一
  • 带方括号的 Uri.EscapeUriString

    这是一个奇怪的问题 但让我们看看它会得到什么样的回应 如果我编写一个控制台应用程序 VS 2013 NET 4 5 1 并执行这行代码 Uri EscapeUriString 我明白了 但是 如果我执行同样的事情 嗯 从技术上来说Uri E
  • 运行时两个注册之间的简单注入器基于动态上下文的注入

    我有一个使用 Simple Injector 进行命令处理程序注册的中介应用程序 并且注入和处理程序均已设置并完美运行 class DoWashingCommandHandler IRequestHandler
  • 指向指针的指针和指向二维数组的指针之间的区别

    如果我有一个二维数组 B 定义为 int B 2 3 1 3 5 2 4 6 Is int p B与 一样int p 3 B int f B printf d f 1 gives 5作为输出 同时printf d f 给出 1 作为答案 为
  • C# Visual Studio 动态代码片段

    我正在开发一个 WinForms 项目 每天都会执行一些重复性的任务 所以我认为创建代码片段 https msdn microsoft com en us library ms165394 v vs 110 aspx会帮助我 但它仅适用于固
  • 错误 C2065:'cout':未声明的标识符

    我正在处理我的编程作业的 驱动程序 部分 但我不断收到这个荒谬的错误 错误 C2065 cout 未声明的标识符 我什至尝试过使用std cout但我收到另一个错误 IntelliSense 命名空间 std 没有成员 cout 当我宣布u
  • 如何处理作为参数传递到方法中的 Lambda 表达式 - C# .NET 3.5

    我对 Lambda 表达式的了解有点不稳定 虽然我可以编写使用 Lambda 表达式 又名 LINQ 的代码 但我正在尝试编写自己的方法 该方法采用一些 Lambda 表达式类型的参数 背景 我正在尝试编写一个方法 该方法从任何其他对象类型
  • 如何在 WCF 中反序列化自定义 SOAP 标头?

    我正在尝试向通过 WCF 的所有 SOAP 请求添加自定义标头 我发现这篇精彩的文章 http blogs msdn com b mohamedg archive 2012 10 21 adding custom soap headers
  • 如何让 PCRE 与 C++ 一起使用?

    这是一个新手问题 但我希望我能尽可能清楚地表达我的问题 我正在尝试用 C 进行模式匹配 我已经从以下位置下载了 PCRE 的 Win32 版本here http gnuwin32 sourceforge net packages pcre
  • 如何在Windows Azure上调用ffmpeg.exe转换音频文件?

    我在 Windows Azure 上运行 Web 角色来接收 AAC 音频文件 通过 base64 字符串上传 并将它们存储到 blob 中 现在效果很好 接下来 我还必须将它们转换为 MP3 并将 MP3 存储到 blob 中 我决定使用
  • 是否可以在 Eclipse 中为除 Java 之外的 Eclipse 编写插件?

    谁能帮我用c 写一个eclipse插件 weekens 和 celavek 感谢您提供的信息 我正在研究 JNI 并将尝试实现它 celavek 我们必须做什么样的主控 控制 在C 和java接口中处理是否风险更大 我的要求是在 Java
  • 更快的 WinSock sendto()

    我使用的是 Windows Server 2008 我的程序是用 C 编写的 我在 while true 循环中使用 WinSock2 和 sendto 来发送数据包 代码如下 while true if c snd gt max c sn
  • 使用反射检测属性的访问修饰符类型

    我编写了一些代码来使用反射查看属性 我已经使用反射从类中检索了属性列表 但是我需要查明该财产是公共的还是受保护的 例如 public string Name get set protected int Age get set Propert
  • 预览MouseMove 与 MouseMove

    我有相当多的 XAML 经验 但最近我注意到我的大多数同事都使用预览鼠标移动代替鼠标移动事件 我一直用鼠标移动它对我很有帮助 但我忍不住问我什么时候应该使用预览鼠标移动什么时候鼠标移动 有什么区别 各自有什么优点和缺点等等 PreviewM
  • 有关 Endian 性和 .Net 的详细信息?

    我有几个关于字节顺序的问题 这些问题足够相关 我保证将它们作为一个问题提出 1 字节顺序是由 Net还是由硬件决定的 2 如果是由硬件决定的 我怎样才能在C 中找出硬件的字节序 3 字节序是否影响二进制交互 例如 OR AND OR 或移位

随机推荐

  • 为什么区域 Google Cloud IP 地址都显示在美国?

    我在 asia east1 区域创建了一个虚拟机 它的 IP 地址为 35 201 212 242 当我在 iplocation net 等服务上查找此 IP 地址时 我被告知它位于美国 我在 australia southeast1 区域
  • Microsoft Office 应用程序的主要互操作程序集

    我正在尝试在我的 Web 服务器上安装 Microsoft Office 互操作程序集 用于从我的网站阅读 Word 文档 我可以只安装程序集吗 或者唯一的方法是安装办公套件 例外情况 Could not load file or asse
  • 查询格式错误,查询名称后没有 start_object

    我正在针对 AWS Elasticsearch 5 1 运行此查询并收到格式错误的查询错误 这是请求的正文 我基本上只是检查该字段在时间范围内是否存在 query bool filter bool must range timestamp
  • C 中文字数值的类型选择

    我想知道这一点 当我尝试将整数值分配给int变量 16 位编译器 整数 2 个字节 让我们说 int a a 40000 无法用将被截断的类型范围来表示 但我看到的是结果值a是 25000 或某个接近的数字 的位模式 这意味着编译器为十进制
  • RealityKit – 如何为自然光创建阴影捕捉器?

    我想创建一架飞机 func getShadowPlane width Float height Float gt ModelEntity let sphereResource MeshResource generatePlane width
  • 如何从网页中提取文本内容? [关闭]

    很难说出这里问的是什么 这个问题是含糊的 模糊的 不完整的 过于宽泛的或修辞性的 无法以目前的形式得到合理的回答 如需帮助澄清此问题以便重新打开 访问帮助中心 help reopen questions 我正在用java开发一个应用程序 它
  • React JS - 如何将 json 数据绑定到下拉列表

    我有一个 React JS 文件 我正在尝试将数据绑定到下拉列表 数据存储在以下测试 API json 文件中 https api myjson com bins okuxu https api myjson com bins okuxu
  • 当 Electron 在后台时避免应用程序节流

    考虑以下示例 setInterval function console log new Date 如果我运行它electron example js在 OS X 下 它会在我的停靠栏中打开一个图标 并开始在控制台上打印时间 然而 如果应用程
  • Google Sheet - 使用 arrayformula 将两列转换为一列(超过 50,000 个字符)

    我正在使用 Google Sheets 并寻找一个数组公式 该数组公式能够将列表分为两列并将其交替排列在一列中 该表包含约 5 000 行 每行超过 35 个字符 我试过这个 transpose split join query trans
  • 如何使用ctrl+c停止tornado web服务器?

    我是龙卷风网络服务器的新手 当我使用 python main tornado py 启动龙卷风网络服务器时 它正在工作 请看下面的代码 import tornado ioloop import tornado web class MainH
  • 缓存施瓦茨变换

    我正在学习 中级 Perl 它非常酷 我刚刚读完 施瓦茨变换 部分 在理解它之后 我开始想知道为什么变换不使用缓存 在具有多个重复值的列表中 转换会重新计算每个值的值 因此我想为什么不使用哈希来缓存结果 这是一些代码 a place to
  • Android-ListView-performItemClick

    当我尝试使用时遇到一些困难执行项目单击ListView 的功能 我想要做的就是以编程方式在列表的第一项中执行单击 我怎样才能做到这一点 我在文档中查找了该函数 但我并不真正理解它的参数 我尝试过类似的事情 myListView perfor
  • 为什么需要更改 IE 设置才能在 Windows 10 上启用 HTTP/2?

    我最近在我正在开发的网站上启用了 HTTP 2 为了做到这一点 我必须 使用 Windows 10 使用支持 HTTP 2 的浏览器 在我的例子中是 Chrome 配置我的 Web 服务器 iis express 以使用 https 为网站
  • Dictionary(Of String, String) 和 IDictionary(Of String, String) 有什么区别

    我可以用 IDictionary 做更多或更少的事情吗 这两个集合有何不同 IDictionary 只是一个接口 一个描述实现类必须执行的操作的契约 Dictionary 是一个实现该接口的具体类 因此必须提供 IDictionary 接口
  • 如何指定测试窗口?

    我需要测试中的屏幕看起来与物理设备 或模拟器 上的屏幕相同 我该怎么做 就我而言 设备 ID 为 Iphone SE 我编写了一个将屏幕截图保存到磁盘的测试 testWidgets test WidgetTester tester asyn
  • ES5 导出的函数无法识别

    我得到了这个 math js const sum a b gt a b const mul a b gt a b export default sum mul 然后在 math test js 中 const sum mul require
  • 将箭头附加到 UIBezierPath

    我需要你的帮助 我正在尝试使用具有可变宽度的 UIBezierPaths 创建一个图形 并由带有两个控制点的贝塞尔曲线组成 现在我想在这些路径的末尾 右侧 添加箭头 有没有办法做到这一点 即通过附加一个包含三角形的较小线宽的子路径 这是我想
  • 正则表达式。如何从该字符串中获取多个匹配项?

    我正在使用 JavaScript 正则表达式 假设我有以下字符串 XXX 1 XXX XXX 2 XXX XXX 3 XXX YYY 1 YYY YYY 2 YYY YYY 3 YYY 我想运行正则表达式并获得以下模式的结果 Match1
  • 替代 __del__ 来获得最终结果并终止类中的进程?

    这个虚拟类类似于我当前的项目 class EndProcess object def init self self Q multiprocessing Queue self p1 multiprocessing Process target
  • 给定以下代码(在 GCC 4.3 中),为什么调用转换为引用两次?

    给定以下代码 在 GCC 4 3 中 为什么在这两种情况下都会调用到引用的转换 class A class B public operator A operator A int main B b A b A b http ideone co