2013-10-31 239 views
4
1 #include <iostream> 
2 using namespace std; 
3 template<typename T> 
4 class Top { 
5 public: 
6  class Sub { 
7   protected: 
8    T age; 
9  }; 
10  class Derived : public Sub { 
11   public: 
12    void printAge() { 
13     cout << age << endl; 
14    } 
15  }; 
16 }; 
17 int main() 
18 { 
19  return 0; 
20 } 

當我complie代碼,我得到以下錯誤:模板類已經嵌套類

test.cpp: In member function ‘void Top<T>::Derived::printAge()’: 
test.cpp:13:25: error: ‘age’ was not declared in this scope 
      cout << age << endl; 

但是,如果它不是一個模板,這將是確定。 我很高興收到你的答案。

+0

用cout << Sub :: age << endl;替換'cout << age << endl;'適用於我。不知道我可以解釋它! –

+0

適用於VS2010 –

+0

「this-> age」也可以工作 – user1233963

回答

1

衍生是一個模板裏的名字。有2種名的標準所定義的:

  • 相關:名字依賴於模板參數,但不是在模板內聲明 。
  • 非依賴:不依賴於模板參數的名稱,以及模板本身的名稱和在其中聲明的名稱。

在生產線cout << age << endl,年齡是一個非依賴名稱應在模板的定義點來解決。那時,編譯器仍然不知道年齡是多少,因爲Top :: sub可能會/可以在以後專用。所以它不會在基類中查找名稱,但只能在封閉範圍內查找。由於在封閉範圍內沒有年齡,編譯器抱怨。

加上this-> or Top :: on age使其依賴於,因此查找規則改變。現在年齡在模板實例化的時候解決了,編譯器已經充分了解了基類,並且可以正確解析名稱。

0
class Top<T>::Derived : public Top<T>::Sub 

是另一種思考Derived繼承的方法。如果這樣想,那麼來自Sub的變量似乎取決於類型T。當您使用依賴於template參數類型的變量時,您通常需要明確(Sub::age)或將其清除爲成員(this->age)。

現在在這種情況下,雖然看起來基數取決於T,但您可以證明基數是什麼。然而,這將取決於標準中的一些精美的措辭,以及編譯器對該角落案例的實施(無論是否成功)。

所以要解決你的問題,在這種情況下使用this->age

0

age依賴於模板類型參數,因此其評估是在模板即時階段。正如您在this thread中看到的,繼承和模板不能很好地工作。在第一階段(聲明)階段檢查派生類中成員的使用,並且(如我上面所述),在第二階段聲明(「解析」)成員。所以編譯器沒有聲明memeber的東西。

解決這個問題的一種方法是通過this指針訪問memeber,強制編譯器檢查基類。