2016-03-18 108 views
1

以下代碼在visual studio 2015中編譯(即使使用/ Za選項)。它不會在gcc和clang上編譯。模板基類的調用方法

struct A 
{ 
}; 

template<typename T> 
struct B 
{ 
    void f() 
    { 
    } 
}; 

template<typename T> 
struct C : B<T> 
{ 
    void f() 
    { 
    } 

    void g() 
    { 
    B::f(); 
    } 
}; 

int main() 
{ 
    C<A> c; 
    c.g(); 

    return 0; 
} 

Demo

GCC - 誤差:無模板參數使用的 '模板結構B'
鐺 - 錯誤: 'B' 不是類,命名空間,或枚舉

哪個編譯器是符合標準規格?規格中的任何含糊之處?

編輯
我已在Cf()有一個更貼切的例證。

回答

3

通常調用在這種情況下,基類的功能,你可以這樣寫:

this->f(); 

如果fg都是靜態的,你當然會無法做到這一點,因此,你可以寫

B<T>::f(); 

這工作,因爲B已經在爲C申報範圍,所以編譯器已經知道它是一個模板。如果單獨執行B::f(),編譯器會給你一個錯誤,因爲它知道B是一個模板,所以它應該有模板參數。

您可能想知道爲什麼允許您在B<T>的定義內省略模板參數,但不在C的定義範圍內。爲了理解這一點,你需要知道每個類都有一個注入類名,它的行爲類似於類定義最開始處聲明的typedef。因此,它是彷彿的B定義開始

typedef B<T> B; 

使用BB<T>定義裏面會發現注入的類名,沒有模板。但是當你在C之內時,這個B是不可見的,因爲它是在B<T>內部聲明的,這是一個依賴基類,並且在非限定名稱查找期間不搜索依賴基類作用域(並且B位於::的左側,所以查找B是不合格的)。這也適用於:

C::B::f(); 

在這種情況下,注入的類名C被找到,並且它是指依賴型C<T>,所以B查找將依賴基類中搜索B<T>和找到想要的注入類名稱

1

問題出在struct C上,函數f from B被調用時沒有模板參數。

0

編譯器不知道您在B::f();中提到,請嘗試將其更改爲B<T>::f();

+0

對,我知道B :: f()的作品。開發跨平臺代碼,很煩人的是一些代碼是用一個編譯器而不是其他編譯器編譯的。我想知道它的標準是什麼,如果三個編譯器可以對齊以提供相同的編譯結果(成功與否)... –