2012-10-12 161 views
4

爲什麼我收到非法引用非靜態成員... typedef?

錯誤C2597:非法引用非靜態成員'derived<<unnamed-symbol>>::T'

,當我嘗試編譯在Visual C++ 2010的x64代碼? (在x86上看起來很好......哪一個是正確的?)

struct base { typedef int T; }; 

template<class> 
struct derived : base 
{ 
    using base::T; 
    derived(T = T()) { } 
}; 

int main() 
{ 
    derived<int>(); 
    return 0; 
} 
+0

我無法重現x64的問題MSVC 11.0 –

+2

我在VS2010 x86上也遇到同樣的錯誤。似乎問題是'T()'默認值。如果將實例更改爲'derived (0);'編譯。不知道什麼是呃逆。 – Praetorian

+1

不應該是'template '或'template '? – Recker

回答

3

由於禁衛軍的評論中提到的問題是與T()默認值。基於錯誤細節,using base::T顯然混淆了編譯器搜索T()作爲調用base的非靜態成員函數,而不是構造T類型的實例。

這是一個有趣的修復工作在MSVC 2005 x86(我還沒有嘗試過任何其他編譯器)。請注意0​​被保留。這或者消歧using base::T或者只是強制T引用繼承類型,而不是引用using(這顯然與編譯器不一樣)。

//... 
template<class> 
struct derived : base 
{ 
    using base::T; 
    derived(T = static_cast<T>(T())) { } //No error 
}; 
//... 

編輯:嘗試改變base到這一點,看看你的錯誤信息:

struct base { struct T{T(){}}; }; 

我得到原始C2597,也是這樣:

錯誤C2440:'默認參數':無法從''轉換爲'base :: T' 沒有構造函數可採取源類型,或構造函數重載解析模棱兩可

我不知道是什麼的編譯器''意味着,但它可能是一個類似的問題與base的原始定義。這編譯罰款,如果我刪除using base::T;線。

+0

哇......這很奇怪。 :) +1很好的答案。 – Mehrdad

0

爲什麼使用using base::T?在基類中定義的類型將在派生類中自動可用。

struct base { typedef int T; }; 
template< class X > 
struct derived : base {}; 
derived<int>::T v = 0; // this is OK in C++ 
+0

我正在使用'base :: T',因爲原始代碼比較複雜(模板等),編譯器抱怨說,如果我沒有給它使用提示,它找不到'T'。 – Mehrdad

+0

因此,如果你可以'typedef',就像STL的所有實現一樣。使用'typedef base :: T T',它應該與所有編譯器一起工作! – BigBoss

0

使用這個代替(應該是不言而喻的):

template<class T> 
struct derived : base 
{ 
    derived(T = T()) { } 
};