簡體   English   中英

g ++和clang ++在模板類中定義的朋友模板函數的不同行為

[英]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.

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