2017-02-03 38 views
1

我有下面的代碼片段:多重定義

template < typename T1, typename T2 > 
class Test 
{ 
    public: 
    Test() = default; 

    private:  
    template < typename T1_, typename T2_ > 
    friend Test< T1_, T2_ > operator*(const Test< T1_, T2_ >& lhs, const Test< T1_, T2_ >& rhs) 
    { 
     return Test< T1_, T2_ >(); 
    } 
}; 

int main(int argc, char* argv[]) 
{ 
    { 
     Test< int, int > t1; 
     Test< int, int > t2; 
     Test< int, int > t3 = t1 * t2; 
    } 

    { 
     Test< double, double > t1; 
     Test< double, double > t2; 
     Test< double, double > t3 = t1 * t2; 
    } 
} 

鏗鏘3.9的代碼編譯好,用gcc 6.3.1,我得到以下錯誤:

redefinition of ‘template<class T1_, class T2_> Test<T1_, T2_> operator*(const Test<T1_, T2_>&, const Test<T1_, T2_>&)’ 
    friend Test< T1_, T2_ > operator*(const Test< T1_, T2_ >& lhs, const Test< T1_, T2_ >& rhs) 

哪個編譯器是正確的?

如果它是gcc,我懷疑,我怎麼才能正確地聲明模板操作符*課堂上。依賴於參數的查找,我需要類內定義。

回答

3

GCC是正確的,作爲Test每個實例定義模板operator*,這是因爲他們的簽名不依賴於T1T2相同。 operator*需求不會模板這裏,只是爲了Test的特定實例的重載:

template < typename T1, typename T2 > 
class Test 
{ 
    friend Test operator*(const Test& lhs, const Test& rhs) 
    { 
     return Test(); 
    } 
}; 

int main(int argc, char* argv[]) 
{ 
    { 
     Test< int, int > t1; 
     Test< int, int > t2; 
     Test< int, int > t3 = t1 * t2; 
    } 

    { 
     Test< double, double > t1; 
     Test< double, double > t2; 
     Test< double, double > t3 = t1 * t2; 
    } 
} 

這反而會定義operator*兩個非模板重載,一個爲Test每個實例。

+0

我需要操作員模板化。然而,課堂上的朋友聲明和課外定義解決了編譯錯誤。謝謝! – Trevir

+0

@Trevir你爲什麼需要它作爲模板? –

+0

乘以不同類型的對象。 '測試< int, int > t1,測試 t2;自動t3 = t1 * t2'是有效的,應該編譯。 – Trevir