2013-01-24 44 views
1

這裏是我的情況:你能模板專門化一個沒有模板化的子類嗎?

基類,沒有模板類型:

struct Thing 
{ 

} ; 

模板類,擴展了非常基礎類

template <typename T> struct VertexWriter : public Thing 
{ 
    template <typename S> 
    bool intersects(S* otherThing) 
    { 
     // has a body, returns T or F 
    } 
} ; 

派生類,具體類型(無模板)

struct Rocket : VertexWriter<VertexPNCT> 
{ 
    template <typename S> 
    bool intersects(S* otherThing) ; // WANTS TO OVERRIDE 
    // implementation in VertexWriter<T> 
} ; 

但是template typename<S> bool VertexWriter<T>::intersects不能被標記爲虛擬的,因爲它是一個模板類。

有很多類來自VertexWriter<VertexPNCT>專業化,所以模板專門VertexWriter<VertexPNCT>將無法​​正常工作。

所以正常的事情是提供模板專業化。

Rocket指定它是一個VertexWriter<VertexPNCT>,所以它不再是模板類。它可以專注於或替代intersects,就好像它是虛擬功能一樣嗎?

回答

0

不,你不能。

模板化成員函數不能是虛擬的。

無論VertexWriter是模板化的,專業的還是普通的類,都沒關係。

1

不,你已經說過你不能使用虛擬函數,它將提供運行時多態性。

也就是說,根據您在改變班級佈局方面的靈活性,您可能可以使用CRTP做些事情。

template <typename T, typename Derived> struct VertexWriter : public Thing 
{ 
    template <typename S> 
    bool intersects(S* otherThing) 
    { 
     return static_cast<Derived*>(this)->insersects_impl(otherThing); 
    } 

    template<typename S> 
    bool insersects_impl(S* otherThing) 
    { 
     // Whatever 
    } 
} ; 

struct Rocket : VertexWriter<VertexPNCT, Rocket> 
{ 
    template <typename S> 
    bool intersects_impl(S* otherThing) { ... } // WANTS TO OVERRIDE 
         // implementation in VertexWriter<T> 
} ; 

intersects的基本實現只是轉發給CRTP函數。如果派生類重寫它,它將使用覆蓋,否則它將回退默認值。請注意,這會讓您的類層次結構複雜化,但可能會完成您要查找的內容。

0

你可以在S模板VertexWriter,使intersects該類模板

template <typename T, typename S> struct VertexWriter : public Thing 
{ 
    virtual bool intersects(S* otherThing) 
    { 
     // has a body, returns T or F 
    } 
} ; 

現在的虛擬功能,你可以在派生類中重寫intersects

template<typename S> 
struct Rocket : VertexWriter<VertexPNCT, S> 
{ 
    virtual bool intersects(S* otherThing) ; // WANTS TO OVERRIDE 
    // implementation in VertexWriter<T> 
}