2015-10-30 63 views
4

我不明白什麼是在下面的代碼段回事:怪異的行爲與運營商定義爲朋友裏面

struct A { }; 

struct B { 
    B() { } 
    B(const A&) { } 

    friend B operator*(const B&, const B&) 
    { 
    return B(); 
    } 
}; 

int main() 
{ 
    B x = A() * A(); 

    return 0; 
} 

當我編譯(既鐺和gcc 4.9.2)我得到「B x = A()* A()」行上的錯誤消息;鏗鏘說「無效的操作數到二進制表達式」。

如果我從班級內部取得運營商*定義,一切都是100%OK!

struct A { }; 

struct B { 
    B() { } 
    B(const A&) { } 

    friend B operator*(const B&, const B&); 
}; 

B operator*(const B&, const B&) 
{ 
    return B(); 
} 

int main() 
{ 
    B x = A() * A(); 

    return 0; 
} 

這是怎麼回事?

+1

由於'operator *()'在函數內部定義爲朋友,所以只能通過[ADL](http://en.cppreference.com/w/cpp/language/adl)找到,而不是正常的不合格的查詢。這種類型的查找要求參數是精確的類型,而不是可以隱式轉換的類型。當您在外部聲明函數時,可以通過正常的非限定查找規則找到它。 – 0x499602D2

+0

@布萊恩我認爲這與聲明函數的位置有關。他在表達中使用的論點也存在問題;他期望'A'被轉換爲'B'。 – 0x499602D2

+0

@ 0x499602D2我不確定它有什麼不同,但我想我會重新打開它,這樣你可以添加一個答案來解釋(等等,你不應該自己重新打開它,因爲你也有一個c + +金徽章? ) – Brian

回答

3

由於operator*()是作爲朋友內部函數定義的,因此只能通過ADL找到,而不是正常的不合格查找。這種類型的查找要求參數是精確的類型,而不是可以隱式轉換的類型。這意味着即使A可以轉換爲B,也無法找到操作員。

當您在類外部聲明函數時,可以通過正常的非限定查找規則找到它。

+0

謝謝,我明白髮生了什麼事。從A到B的預期轉換實際上似乎沒有與問題非常相關,正如可以在Brian所鏈接的問題中看到的一樣(http://stackoverflow.com/questions/5391927/g-4-5-着 - 找向朋友推薦功能)。 – Fernando