2012-11-08 35 views

回答

1

friend函數不是成員函數;你只需在類中聲明友誼,但函數總是一個自由函數。如果你在一個類模板類中定義它,你將最終定義它作爲模板實例的次數。

我會盡力用代碼解釋。對於我們來說,你的代碼是相同的:

template<typename T> struct foo{ 
}; 

template<> struct foo<int>{ 
    friend void bar(); 
}; 

void bar() {}; 

template<> struct foo<double>{ 
    friend void bar(); 
}; 

void bar() {}; 

int main(){ 
    foo<int>(); foo<float>(); 
} 
+0

所以'bar'的範圍在上述情況下是全局範圍? – M3taSpl0it

+1

是的,全球範圍。 – Gorpik

0

你有定義bar在你的struct裏面。這導致bar func的雙重定義,每個模板實例化一次。 Friend應該只是某個實體的聲明。實體本身(你的情況下的函數)應該在其他地方定義。將您的bar定義替換爲friend void bar();聲明並在另一個地方定義您的bar

+0

請再讀一遍這個問題,當然在同一個單元裏有兩個def但是bar的範圍是什麼? – M3taSpl0it

1

因爲你的代碼定義的自由功能void bar()兩次,或讓寧說,你的模板會爲每一個實例化一個新功能名爲void bar(),這恰好有每次完全相同的簽名,因此您有多個具有相同簽名的功能,這是違反ODR的。

手頭的技術被稱爲「朋友名注入」,因爲您將名稱注入到周圍的名稱空間中。