[英]Qualified friend function template instantiation
查看C++ 模板:完整指南(第 2 版) /今天早上的官方網站我遇到了一個我不太明白的部分(如果你有這本書,則為 12.5.2)。 省略這里似乎無關的內容:
如果名稱 [在朋友聲明中] 后面沒有尖括號,則有兩種可能性
如果名稱不合格 [...]
如果名稱是限定的(它包含
::
),則名稱必須引用先前聲明的函數或函數模板。 匹配函數優於匹配函數模板。 但是,這樣的朋友聲明不能是定義。
使用以下代碼
void multiply(void*);
template <typename T>
void multiply(T);
class Comrades {
// ... skipping some friends that do not effect the error message
friend void ::multiply(int); // refers to an instance of the template
// ...
};
gcc 錯誤:
error: ‘void multiply(int)’ should have been declared inside ‘::’
friend void ::multiply(int);
^
叮當錯誤:
error: out-of-line declaration of 'multiply' does not match any
declaration in the global namespace
friend void ::multiply(int);
^~~~~~~~
我正在嘗試深入了解這一點,並且我已經重新輸入了幾次代碼(盡管如果有人擁有這本書,則再次輸入......)。 規則是否正確而編譯器是錯誤的? 代碼不是規則的正確示范嗎?
完整的代碼包括一個較早的朋友函數定義:
class Comrades {
friend void multiply(int) { }
friend void ::multiply(int);
}
哪個 clang 接受而 gcc 拒絕(這是一個不同的問題)。 在任何一種情況下,它都沒有證明作者聲明的規則,它是第二個引用同一類中較早一個的規則。
書是對的。 [temp.friend]p1 - 突出顯示相關部分:
對於不是模板聲明的友元函數聲明:
如果朋友的名字是合格或不合格的模板ID ,[...]
如果朋友的名字是一個合格的 id並且在指定的類或命名空間中找到匹配的非模板函數,[...]
如果友元的名稱是限定 ID並且在指定的類或命名空間中找到匹配的函數模板,則友元聲明引用該函數模板的推導特化
[...]
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.