void func(const int &) { std::cout << "c lv ref\n"; }
void func(int &&) { std::cout << "rv ref\n"; }
func(1);
由于const左值引用能够接受各种类型的数据(const和非左值,const和非右值),我想知道上述代码输出“rv ref”的保证是什么。这是标准化的还是编译器相关的?
void func(const int &) { std::cout << "c lv ref\n"; }
void func(int &&) { std::cout << "rv ref\n"; }
func(1);
由于const左值引用能够接受各种类型的数据(const和非左值,const和非右值),我想知道上述代码输出“rv ref”的保证是什么。这是标准化的还是编译器相关的?
我的先前解释是错误的 - 正如 T.C.在评论中提到的,两个重载函数拥有相同的隐式转换序列,而消歧是根据标准定义的特殊选项来进行的。
§13.3.3.1.4 [over.ics.ref], 第1段
当引用类型的参数直接绑定到一个参数表达式时,除非参数表达式的类型是参数类型的派生类,否则隐式转换序列为标识转换([dcl.init.ref]),在这种情况下,隐式转换序列为派生到基类转换([over.best.ics])。[...]
如果参数类型相同,则应用于两个重载函数的隐式转换序列为标识转换。这仍然不能消除两个函数之间的歧义。
这里指定了一种消除歧义的方法:
§13.3.3.2 [over.ics.rank], par 3.2.3
[如果标准转换序列S1优于标准转换序列S2,则] S1和S2都是引用绑定([dcl.init.ref])且没有引用非静态成员函数声明的隐式对象参数,S1绑定到右值引用并且S2绑定到左值引用。[...]
引用的两个隐式转换序列相同时:
将右值绑定到右值引用的序列是最佳的。
将右值绑定到左值引用的序列比上述序列差。