簡體   English   中英

合格的友元函數模板實例化

[英]Qualified friend function template instantiation

查看C++ 模板:完整指南(第 2 版) /今天早上的官方網站我遇到了一個我不太明白的部分(如果你有這本書,則為 12.5.2)。 省略這里似乎無關的內容:

如果名稱 [在朋友聲明中] 后面沒有尖括號,則有兩種可能性

  1. 如果名稱不合格 [...]

  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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM