![](/img/trans.png)
[英]Is a friend function template defined in the class available for lookup? clang++ and g++ disagree
[英]g++ and clang++ different behaviour with friend template function defined inside a template class
另一個問題是“g ++和clang ++之間誰是對的?” 對於C ++標准大師。
以下代碼
template <int>
struct foo
{
template <typename>
friend void bar ()
{ }
};
int main ()
{
foo<0> f0;
foo<1> f1;
}
使用clang ++編譯沒有問題(只有兩個“未使用的變量”警告)但是給出以下錯誤
tmp_002-11,14,gcc,clang.cpp: In instantiation of ‘struct foo<1>’:
tmp_002-11,14,gcc,clang.cpp:27:12: required from here
tmp_002-11,14,gcc,clang.cpp:20:16: error: redefinition of ‘template<class> void bar()’
friend void bar ()
^~~
tmp_002-11,14,gcc,clang.cpp:20:16: note: ‘template<class> void bar()’ previously defined here
用g ++編譯。
像往常一樣,問題是:誰是對的? g ++或clang ++?
在我的Debian平台上查看了clang ++ 3.9.1和g ++ 6.3.0。 但是,嘗試使用Wandbox,似乎與更新的版本相同。
GCC在這種情況下是對的。
相關的標准措辭在[temp.inst] / 2中 :
類模板特化的隱式實例化導致
- 未刪除的類成員函數,成員類,作用域成員枚舉,靜態數據成員,成員模板和朋友的聲明的隱式實例化,但不是定義的隱式實例化; 和
[...]
但是,為了根據6.2和12.2確定實例化的重新聲明是否有效,與模板中的定義相對應的聲明被認為是定義。 [ 例如: [...]template<typename T> struct Friendly { template<typename U> friend int f(U) { return sizeof(T); } }; Friendly<char> fc; Friendly<float> ff; // ill-formed: produces second definition of f(U)
- 結束例子 ]
與朋友相關的部分由DR2174添加到本段並在C ++ 17中發布(這是一個缺陷報告,因此編譯器也應該將它應用於以前的標准版本)。
最新版本的MSVC和EDG在嚴格模式下也拒絕代碼,抱怨重新定義。
[temp.inject] / 1有點相關,但它只談到朋友的功能,而不是朋友的功能模板:
可以在類模板中聲明好友類或函數。 實例化模板時,會將其朋友的名稱視為在實例化時明確聲明了特化。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.