函数重载优先级(参考) [英] 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和non-lval,const和非右值),所以我想知道上面的代码将打印"rv ref"的保证是什么.是标准化的还是依赖编译器的?
Since const lvalue reference is able to accept every kind of data (const and non- lval, const and non- rvalue), I wonder what is the guarantee that the code above will print "rv ref". Is it standardized or compiler dependent?
推荐答案
My previous explanation was incorrect - as T.C. mentioned in the comments, both overloads have the same implicit conversion sequence, and the disambiguation happens as a special tie-breaker defined in the standard.
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]). [...]
如果参数类型相同,则应用于两个重载的隐式转换序列是身份转换.这尚未消除这两个功能的歧义.
If the argument types are the same, the implicit conversion sequence applied to both overloads is the identity conversion. This does not yet disambiguate the two functions.
在这里将消歧指定为抢七游戏:
The disambiguation is specified as a tie-breaker here:
§13.3.3.2 [over.ics.rank] ,参数3.2.3
[如果 ...,标准转换序列 S1比标准转换序列S2更好,则是>>] S1和S2是参考绑定([dcl.init.ref])都没有引用未声明没有ref限定符的非静态成员函数的隐式对象参数,,并且S1将右值引用绑定到右值,而S2则将左值引用绑定.[...]
[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. [...]
引号表示,对于两个身份隐式转换序列:
-
将右值绑定到右值引用的序列是最好的.
The sequence binding an rvalue to rvalue reference is the best one.
将右值绑定到左值引用的序列比上述序列差.
The sequence binding an rvalue to an lvalue reference is worse than the aforementioned one.
[...],如果S1和S2是引用绑定[...]
需要 const
来将右值绑定到 const&
的原因可以在这里找到:
The reason why const
is required to bind rvalues to const&
can be found here:
§8.6.3 [dcl.init.ref] ,参数5.2
对类型"cv1 T1"的引用由类型"cv2 T2"的表达式初始化,如下所示:
[如果引用是左值引用和初始值设定项表达式...]
否则,引用应为对非易失性const类型的左值引用(即cv1为const),或者引用应为右值引用.>
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.
如果初始化器表达式 [...] 是右值(但不是位字段)或函数左值且引用了"cv1 T1"-与"cv2 T2"兼容
If the initializer expression [...] is an rvalue (but not a bit-field) or function lvalue and "cv1 T1" is reference-compatible with "cv2 T2"
这篇关于函数重载优先级(参考)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!