c++ - 函数重载优先级(引用)

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

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”的保证是什么。它是标准化的还是依赖于编译器的?

最佳答案

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


§13.3.3.1.4 [over.ics.ref], par. 1

When a parameter of reference type binds directly ([dcl.init.ref]) to an argument expression, the implicit conversion sequence is the identity conversion, unless the argument expression has a type that is a derived class of the parameter type, in which case the implicit conversion sequence is a derived-to-base Conversion ([over.best.ics]). [...]

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

此处将消歧指定为决胜局:

§13.3.3.2 [over.ics.rank], par 3.2.3

[Standard conversion sequence S1 is a better conversion sequence than standard conversion sequence S2 if...] S1 and S2 are reference binding ([dcl.init.ref]) and neither refers to an implicit object parameter of a non-static member function declared without a ref-qualifier, and S1 binds an rvalue reference to an rvalue and S2 binds an lvalue reference. [...]

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

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

  • 将右值引用绑定(bind)到左值引用的序列比前面提到的更糟糕。


[...] if S1 and S2 are reference binding [...]

可以在此处找到const 将右值绑定(bind)到const& 的原因:

§8.6.3 [dcl.init.ref], par 5.2

A reference to type “cv1 T1” is initialized by an expression of type “cv2 T2” as follows:

[If the reference is an lvalue reference and the initializer expression...]

Otherwise, the reference shall be an lvalue reference to a non-volatile const type (i.e., cv1 shall be const), or the reference shall be an rvalue reference.

If the initializer expression [...] is an rvalue (but not a bit-field) or function lvalue and “cv1 T1” is reference-compatible with “cv2 T2”

关于c++ - 函数重载优先级(引用),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41505121/

相关文章:

c++:数组中的类成员有多远(以字节为单位)?

c++ - 为什么 "missing double brace warning"用于 Clang 12 中的 BaseClass 聚合初始化而不是 Clang 13 或 GCC 11?

c++ - 为什么skb_transport_header计算不正确?

c++ - 我可以将 std::ostream& 传递给需要 std::ofstream 的函数吗

Xcode 4.2 — 将派生文件添加到项目

c++ - 在 c/c++ 中分配指针

c++ - 阐明表达式的值类别

c++ - 类名前的宏

c++ - OpenMP 中的信号

reference - 如何将引用元组转换为元组的引用?