oli*_*ist 16 c++ overloading rvalue-reference language-lawyer
#include <iostream>
using namespace std;
void func(int (&ref)[6]) { cout << "#1" << endl; }
void func(int * &&ref) { cout << "#2" << endl; }
int main()
{
int arr[6];
func(arr); // g++(5.4): ambiguous, clang++(3.8): #2, vc++(19.11): #1
return 0;
}
Run Code Online (Sandbox Code Playgroud)
这两个函数都是完全匹配.以下是标准的引用:
标准转换序列S1是比标准转换序列S2更好的转换序列
...
S1和S2是引用绑定(8.5.3),并且都不引用没有ref-qualifier声明的非静态成员函数的隐式对象参数,S1将rvalue引用绑定到rvalue,S2绑定左值引用.
这不是意味着第二个更好吗?
更新:
有一个相关的问题.以下代码是它的简化版本.
#include <iostream>
using namespace std;
void func(int *&) { cout << "#1" << endl; }
void func(int *&&) { cout << "#2" << endl; }
int main()
{
int arr[6];
func(arr); // g++(5.4) and clang++(3.8): #2, vc++(19.11): ambiguous
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我认为这取决于特定短语的含义。
\n\n这两种转换是等效的,因为我们排除了左值转换(基本上,数组实际上是一个指针,因此它不算作转换),因此我们进入了您在[over.ics.rank]中指出的下一个决胜局:
\n\n\n\n\nS1 和 S2 是引用绑定,两者都没有引用未使用 ref 限定符声明的非静态成员函数的隐式对象参数,并且 S1 将右值引用绑定到右值,S2 绑定左值引用
\n
这个案例适用吗?我们确实有两个引用绑定:
\n\nint arr[6];\nint (&a)[6] = arr; // #1\nint *&& b = arr; // #2\n
Run Code Online (Sandbox Code Playgroud)\n\n这里,#1 绑定了一个左值引用。#2 属于[dcl.init.ref]:
\n\n\n\n\n否则,初始化表达式将隐式转换为 \xe2\x80\x9ccv1 T1\xe2\x80\x9d 类型的纯右值。应用临时具体化转换并将引用绑定到结果。
\n
arr
隐式转换为 类型的纯右值int*
,然后绑定到b
。
所以现在的问题是 - [over.ics.rank] 中的限制意味着什么?这可能意味着:
\n\narr
。arr
不是右值(它是左值),因此会跳过此决胜局,并且不会应用后续的决胜局。我倾向于支持 gcc 的实现。否则,“将右值引用绑定到右值”这句话的意义是什么?右值引用不能绑定到左值。这是多余的。也就是说,对于这种解释来说,它的措辞也很尴尬。
\n\n事实上,我将其称为措辞错误。
\n 归档时间: |
|
查看次数: |
423 次 |
最近记录: |