因爲value
是不合格的名稱,並且在名稱查找的第一階段,編譯器將不知道這是一個數據成員從基類繼承(它尚未實例化Base<T>
尚未)。因此,它會搜索全局命名空間,並沒有發現所謂的可變value
;因此,它會發出錯誤。
這裏是解決這個問題的一個典型方法:
template <class T>
struct Derived : public Base<T> {
int getValue() { return this->value; }
// ^^^^^^
};
顯式地解引用this
告訴編譯器後面的名稱是(可能繼承)的名稱數據成員,並且查找應被延遲到成員函數實際上是實例化的地步。當然,你做的解決方案:
return Base<T>::value;
同樣出色,因爲它也告訴value
從基類繼承Base<T>
編譯器。
對於所關注的Base<std::string>
推導,編譯器可以立即去找了Base<std::string>
是否包含一個名爲value
(因爲它不依賴於任何模板參數)的數據成員,如果是這樣的話,它就能確定表達式是格式良好的。
但是,如果你的基類是Base<T>
,其中T
是在名稱查找的第一階段未知,編譯器分不清什麼是value
(的Base
針對不同T
小號特甚至可能沒有value
在所有) 。
段落14.6/C++的11標準的3:
在一類或類模板的定義中,如果一個基類依賴於模板參數,基類 範圍並不在類模板 或成員的定義點處或在類模板或成員的實例化期間在非限定名稱查找期間進行檢查。 [...] [實施例:
struct A {
struct B {/.../};
int a;
int Y;
};
int a;
template<class T> struct Y : T {
struct B {/.../};
B b; // The B defined in Y
void f(int i) { a = i; } // ::a
Y* p; // Y<T>
};
Y<A> ya;
成員A::B
,A::a
,和模板參數A
的A::Y
不影響 Y<A>
名稱的結合。 - 結束示例]
優秀的答案。 – Oswald 2013-04-04 14:39:15
@Oswald:謝謝,很高興我能幫到 – 2013-04-04 14:40:54
非常好,我可以隨時添加:)。 – 2013-04-04 15:04:05