2012-05-23 17 views
3

如果我帶班工作,一切都只是罰款:爲什麼我需要在模板繼承中使用範圍解析?

struct Base1 { 
    int value; 
    Base1(int value) : value(value) { } 
}; 

struct Test1 : public Base1 { 
    int getValue() { return value; } 
    Test1(int value) : Base1(value) { } 
}; 

但模板範圍分辨率需要:

template <typename T> 
struct Base { 
    T value; 
    Base(T value) : value(value) { } 
}; 

template <typename T> 
struct Test : public Base<T> { 
    typedef Base<T> parent; 
    T getValue() { return parent::value; } // why do I need to use parent:: here? 
    Test(T value) : parent(value) { } 
}; 

沒有範圍解析我收到錯誤'value' was not declared in this scope(用gcc編譯器)。 爲什麼?

+0

如果你定義Test如下:'Test Test :Public Base '? – Brady

+0

@Brady:然後我收到一個錯誤''Test'不是模板' - 模板必須在專門化之前創建。 –

+0

@Brady:編譯器會給你一個錯誤。正確的C++語法是OP使用的語法。 – Gorpik

回答

6

因爲編譯器不知道value依賴於模板參數。因此,它會嘗試在第一階段(在實例化模板之前)解決它,並且失敗。

這兩個選項是使用作用域分辨率,或者使用this->value。由於this始終是一個獨立名稱,因此這將強制評估在第二階段進行。

http://ideone.com/07odY

編輯:至於到爲什麼它需要在全部完成:

雖然Test<T>Base<T>派生,由於模板專業化你可以做Base<std::string>(舉例來說)是完全不同的比正常Base<T>,並沒有一個名爲value成員,或者它可以是不同的類型,或任何東西。通過強制它成爲一個依賴名稱,編譯器被迫等待,直到它知道在檢查之前涉及的實際類型。

+0

+1進行編輯和說明。 – Gorpik

3

因爲沒有其他方法可以告訴編譯器(因爲它沒有在Test的主體中定義),所以value是一個從屬名稱。你迫使編譯器說:「好的!當我說有這樣的成員valueT類型時相信我。」

+0

我知道這是脫離主題,但我只是愛道格拉斯亞當斯! :) – Brady

+0

這真的很酷,在我的瀏覽器,你42秒前回答! :) – Brady

+0

@Brady:大聲笑!是的,我也是 - 這個男人的巨大粉絲!很高興有任何幫助,歡呼! – dirkgently

相關問題