2017-09-08 118 views
16
#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; 
} 

這兩個函數都是完全匹配的。下面是標準的報價:左值參考值和右值參考值之間的過載分辨率

標準轉換序列S1是,如果

...

S1和S2是參考綁定(8.5比 標準轉換序列S2更好的轉換序列。 3),既沒有引用ref-qualifier,也沒有引用 的非靜態成員函數的隱式對象參數,並且S1將右值引用綁定到右值 ,並且S2綁定了左值引用。

這不是暗示第二個更好嗎?

更新時間:

There是一個相關的問題。下面的代碼是它的簡化版本。

#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; 
} 
+0

你的意思是「更好」是什麼意思? – user463035818

+2

Fwiw,這個[成功與clang](https://godbolt.org/g/gi1C9n) – WhozCraig

+0

這將打開'int(&ref)[6]'是否是一個「左值引用」,如引用中引用。儘管這是一個參考,但可以認爲這不是對左值的參考。如果是,你可以指定'ref',即'ref = '。但你不能。 –

回答

3

我認爲這取決於特定的短語是什麼意思。

兩個轉換是等效的,因爲我們排除lvalue transformations(基本上,一個數組是一個有效的指針,以便它不作爲轉換計數),所以我們進入您在[over.ics.rank]指出,接下來的決勝局:

S1和S2是參考綁定和既不是指不具有REF-限定符中聲明的非靜態成員函數的一個隱式對象參數,和S1結合一個rvalue一個右值參考和S2結合左值參考

這種情況適用嗎?我們確實有兩個參考綁定:

int arr[6]; 
int (&a)[6] = arr; // #1 
int *&& b = arr; // #2 

這裏,#1綁定一個左值引用。 #2屬於[dcl.init.ref]

否則,初始化表達式隱式轉換爲類型「cv1 T1」的prvalue。臨時實現轉換被應用並且參考被綁定到結果。

arr隱式轉換爲int*類型的prvalue,然後將其結合到b


所以現在的問題是 - [over.ics.rank]中的限制是什麼意思?這可能意味着:

  • 一個右值引用,通常綁定到右值。這顯然是鏗鏘的解釋。右值引用綁定到從arr的預值轉換臨時實現。
  • 具體而言,參數表達式是一個右值,它與右值引用參數綁定。這是gcc的解釋,由於arr不是一個右值(這是一個左值),所以這個決勝球被跳過,並且沒有後來的決勝盤適用。

我傾向於在這裏傾向於gcc的實現。否則,短語「綁定右值引用右值」的意思是什麼?右值引用不能綁定到左值。這是多餘的。也就是說,對於這種解釋也很笨拙。

現在,我將其稱爲一個措辭錯誤。

+0

對於編譯器來說,如果某些東西不能按照標準工作,那麼就有適當的網頁來共享挫敗感......有沒有辦法在出現標準缺陷時提交報告? –

+1

@ W.F。有。 https://isocpp.org/std/submit-issue – NathanOliver

+0

@NathanOliver謝謝! –