2010-12-22 75 views
4

我知道基類模板的成員名稱隱藏在派生類的範圍內,因此必須使用this->fooBase<T>::foo來訪問。但是,我記得C++也允許你使用關鍵字using,它可以在派生類函數中派上用場,它經常訪問基類變量。所以,爲了避免在任何地方混淆this->的功能,我想使用using關鍵字。「使用」指令在模板內失敗

我知道我以前做過這件事,但無論出於何種原因,我現在都無法使用它。我可能只是在做一些愚蠢的事,但下面的代碼不會編譯:

template <class T> 
struct Base 
{ 
    int x; 
}; 

template <class T> 
struct Derived : public Base<T> 
{ 
    void dosomething() 
    { 
    using Base<T>::x; // gives compiler error 
    x = 0; 
    } 
}; 

int main() 
{ 
    Derived<int> d; 
} 

錯誤,(用GCC 4.3)是:error: ‘Base<T>’ is not a namespace

爲什麼不這項工作?

回答

7

它不起作用,因爲C++語言沒有這樣的功能,從來沒有。類成員的使用聲明必須是成員聲明。這意味着您只能在類作用域中使用,但不能在本地作用域中使用。這一切都與模板無關。

換句話說,您可以將您的使用聲明爲類範圍

struct Derived : public Base<T> { 
    ... 
    using Base<T>::x; 
    ... 
}; 

,但你不能把它的功能中。

名稱空間成員的使用聲明可以放在本地作用域中,但類成員的使用聲明不可以。這就是錯誤消息抱怨Base<T>不是命名空間的原因。

3
template <class T> 
struct Base 
{ 
    int x; 
}; 

template <class T> 
struct Derived : public Base<T> 
{ 
    using Base<T>::x; 
    void dosomething() 
    { 
    x = 0; 
    } 
}; 

int main() 
{ 
    Derived<int> d; 
} 

正如別人所說,它只是在工作範圍內工作。

3

外部類的範圍(如果你在一個塊等),你只能在使用聲明中命名命名空間成員。

如果你不想地方使用聲明成Derived範圍(這IMO是有利的解決方案),你的其他選擇是使用

int &x = this->x; 
x = 0; 

應當指出的是,這是一個參考在語義上是不同的,因爲它

  • 強制定義爲Base<T>::x存在,這可能不是靜態常量數據成員的情況下
  • 部隊Base<T>::xint&類型或可轉換爲int&類型。

否則,如果你想避免再次使用this->,我沒有看到其他選項。