2011-06-06 97 views
2

想象以下場景:C++:調用重載函數的派生類作爲參數太多(沒有明確的轉換)

template<class T> 
    void myFunction(T *) 
    { 
     //do nothing 
    } 

    void myFunction(myBase * _base) 
    { 
     //do something with _base 
    } 

int main(int argc, const char* argv[]) 
{ 
    myDerivedFromBase * ptr = new myDerivedFromBase; 
    myFunction(ptr); //calls the templated version 

    myFunction(static_cast<myBase*>(ptr)); //calls the correct version 

    delete ptr; 
} 

基本上我想要實現的模板函數被調用爲指針,不是從派生我的基地。如果一個ptr是從myBase派生的,我希望第二個版本的myFunction在沒有顯式強制轉換的情況下被調用。那可能嗎?

回答

6

利用類型的特徵,以防止模板的結合:

template<typename T> 
typename std::enable_if<!std::is_base_of<myBase, T>::value, void>::type myFunction(T*) 
{ 
} 

如果你不能用C++ 0x中,使用Boost的類型特徵庫,而不是。

+0

這不會出現運行時速度損失,因爲它發生在編譯時正確嗎? – moka 2011-06-06 14:40:33

+0

是的,這完全是編譯時間(它阻止編譯器匹配來自myBase派生類的模板)。運行時沒有額外的事情發生。 – Sven 2011-06-06 14:43:06

+0

好吧,我試過這種使用提升,但我似乎無法得到它的工作。我得到以下錯誤:<!提振:: is_base_of ::值,bool>的模板 類型名稱的boost :: enable_if ::鍵入myFunc的(T * _bla) { \t的cout << 「喇嘛」 << ENDL; } /錯誤:類型/在參數1模板參數列表值不匹配「的模板<類電導率,類T>結構的boost :: enable_if」 錯誤:預期的類型時,得到了「升壓:: is_base_of ::值' – moka 2011-06-06 15:39:32

-1

如果你可以使用一個指向基地址的指針(見下面),你可以使用模板特化: #include using namespace std;

class myBase {}; 
class myDerivedFromBase: public myBase {}; 

template<class T> 
void myFunction(T *) 
{ 
    cout << "Most general function." << endl; 
} 

template<> 
void myFunction(myBase * _base) 
{ 
    cout << "Specialized for myBase." << endl; 
} 

int main(int argc, const char* argv[]) 
{ 
    myDerivedFromBase * ptr = new myDerivedFromBase; 
    myFunction(ptr); 
    delete ptr; 

    myBase* bptr = new myBase; 
    myFunction(bptr); 
    delete bptr; 

    bptr = new myDerivedFromBase; 
    myFunction(bptr); 
    delete bptr; 
} 
+0

這只是使用隱式轉換而不是顯式轉換。 – Sven 2011-06-06 14:52:44

+0

OP正試圖包括更多的情況,而不僅僅是完全匹配。 – 2011-06-06 14:53:25

相關問題