2010-08-12 87 views
1

我可以有一個typedef函數指針在這樣的類:的typedef函數指針繼承

template<typename T> 
class MyClass 
{ 

public: 

typedef T (*fptr)(T); 

    void doSomething(fptr my_fptr) { /*...*/ } 

}; 

,這工作得很好。但如果我從這樣的類繼承,如下所示:

template<typename T> 
class MyClass 
{ 

public: 

typedef T (*fptr)(T); 

    virtual void doSomething(fptr my_fptr) = 0; 

}; 

template<typename T> 
class MyOtherClass: public MyClass<T> 
{ 

public: 

    void doSomething(fptr my_fptr) { /*...*/ } 

}; 

編譯器抱怨說fptr是未定義的。有沒有繼承這樣的函數指針typedefs的方法?謝謝, james

+0

你使用什麼編譯器?我不會抱怨這個。 – 2010-08-12 15:02:04

+0

@Seb Rose:我猜你正在使用VS ...這是該編譯器的已知問題。根據標準的代碼不應該編譯。 – 2010-08-12 15:07:57

+0

@dribeas - 感謝那 – 2010-08-12 15:19:52

回答

1

你應該能夠繼承這樣的公共typedefs。

您是否嘗試過這樣的事情,以確保編譯器知道這是一個父類型:

void doSomething(typename MyClass<T>::fptr my_fptr) { /*...*/ } 
+0

這樣做了......我剛開始時錯過了typename。 – 2010-08-12 15:10:52

0

我覺得編譯器需要更多的信息,由於模板:

嘗試 typename MyClass<T>::fptr

4

問題不在於繼承,而在於模板是從另一個模板的實例繼承的,通過它自己的模板參數作爲參數。也就是說,它是從依賴類型繼承的(MyClass<T>取決於類型T)。

該語言要求在執行類型替換之前對模板進行驗證,並且在第一次傳遞期間,將驗證所有非依賴名稱。當編譯器看到fptr時,它不依賴於類型T,因此它會嘗試將它定位在模板外部作爲名稱空間級別符號並失敗。不允許用類型實例化MyBase(沒有替換類型),因此整個MyBase都是未知的,並且沒有符號可以在那裏查找(不用替換類型,編譯器不知道是否存在具體專業MyBase)。

最簡單的辦法是增加一個本地的typedef:

typedef MyBase<T> base_type; 
typedef typename base_type::fptr fptr; 

或完全限定通話:

void doSomething(typename MyClass<T>::fptr) ... 
0

的問題是,該定義是依賴於一個模板參數的基類(被稱爲從屬基類);直到模板實例化該基類的實際內容才知道它;不同的專業可能有不同的成員。所以,你必須明確地指出,這是一個類型,在基類中定義:

template<typename T> 
class MyOtherClass: public MyClass<T> 
{ 
    typedef typename MyClass<T>::fptr fptr; 
    // now fptr is available in this class template 
}; 

要訪問相關的基類的成員,你可以把它們稱爲要麼MyClass<T>::memberthis->member