【问题标题】:Function overloads priority (references)函数重载优先级(参考)
【发布时间】:2017-05-21 04:22:05
【问题描述】:
void func(const int &) { std::cout << "c lv ref\n"; }
void func(int &&) { std::cout << "rv ref\n"; }

func(1);

既然 const 左值引用能够接受各种数据(const 和非 lval,const 和非右值),我想知道上面的代码打印“rv ref”的保证是什么。它是标准化的还是依赖于编译器的?

【问题讨论】:

    标签: c++ reference language-lawyer rvalue-reference overloading


    【解决方案1】:

    我之前的解释是不正确的 - 正如T.C. mentioned in the comments,两个重载具有相同的隐式转换序列,并且消歧发生在标准中定义的特殊决胜局。


    §13.3.3.1.4 [over.ics.ref],同级。 1

    当引用类型的参数直接绑定 ([dcl.init.ref]) 到参数表达式时,隐式转换序列是恒等转换,除非参数表达式具有type 是参数类型的派生类,在这种情况下,隐式转换序列是派生到基转换([over.best.ics])。 [...]

    如果参数类型相同,则应用于两个重载的隐式转换序列身份转换。这还没有消除这两个功能的歧义。

    消歧在这里被指定为决胜局:

    §13.3.3.2 [over.ics.rank],第 3.2.3 条

    [标准转换序列如果...]S1和S2是引用绑定 ([dcl.init.ref]) 并且既不引用声明的非静态成员函数的隐式对象参数,也没有引用限定符,并且 S1 将右值引用绑定到右值,S2 绑定左值引用。 [...]

    引号暗示,在两个身份隐式转换序列的情况下:

    • 将右值绑定到右值引用的序列是最好的。

    • 将右值绑定到左值引用的序列比上述序列更糟糕。


    [...] 如果 S1 和 S2 是引用绑定 [...]

    const 需要绑定右值到const&amp; 的原因可以在这里找到:

    §8.6.3 [dcl.init.ref],第 5.2 段

    对“cv1 T1”类型的引用由“cv2 T2”类型的表达式初始化,如下所示:

    [如果引用是左值引用和初始化表达式...]

    否则,该引用应为对非易失性 const 类型的左值引用(即 cv1 应为 const),或该引用应为右值引用。 >

    如果初始化表达式 [...] 是右值(但不是位域)或函数左值并且“cv1 T1”是引用- 兼容“cv2 T2”

    【讨论】:

    • 不,它不是这样工作的。在这两种情况下都有一个 ICS(如果您不能形成一个 ICS,则该功能不可行),并且两者都是身份转换。这由[over.ics.rank]/3.2.3 中的决胜局控制。
    • @T.C.我没能理解标准。为传播错误信息道歉 - 我编辑了这个问题,希望它是正确的。
    • @Criss:您可能想再看一遍答案,因为上一个答案不正确 - 抱歉。
    • 好的,感谢 VittorioRomeo 的更正。谢谢@T.C.因为睁大眼睛:)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-12-03
    • 2013-03-16
    • 1970-01-01
    • 2015-11-15
    • 2021-08-10
    • 1970-01-01
    相关资源
    最近更新 更多