函数重载优先级(参考)
Function overloads priority (references)
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" 的保证是什么。它是标准化的还是依赖于编译器的?
我之前的解释不正确 - 因为 ,两个重载具有相同的 隐式转换序列 ,并且消歧是作为标准。
§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. [...]
引号暗示,在两个身份隐式转换序列的情况下:
将右值绑定到右值引用的序列是最好的。
将右值引用绑定到左值引用的序列比前面提到的更糟糕。
[...] if S1 and S2 are reference binding [...]
可以在此处找到 const
将右值绑定到 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”
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" 的保证是什么。它是标准化的还是依赖于编译器的?
我之前的解释不正确 - 因为
§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. [...]
引号暗示,在两个身份隐式转换序列的情况下:
将右值绑定到右值引用的序列是最好的。
将右值引用绑定到左值引用的序列比前面提到的更糟糕。
[...] if S1 and S2 are reference binding [...]
可以在此处找到 const
将右值绑定到 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”