2013-09-24 60 views

回答

6

您可以結合使用std::is_base_ofstatic_assert

template<class T> 
class MyClass 
{ 
    static_assert(std::is_base_of< OtherClass, T >::value, "T does not extend OtherClass"); 

public: 
    MyClass(); 
}; 

(你可以,當然,也使OtherClass額外的模板參數的情況下,你需要更靈活)

+0

謝謝你的解決方案 –

1

如果要聲明模板類(即你template<class T, class OtherClass>做了什麼),那麼你必須使用模板你聲明。由於您沒有在MyClass中使用TOtherClass,因此會出現編譯器錯誤。

至於如何實現T extends OtherClass在C++中,它不是那麼簡單,因爲C++有多重繼承,但是你可以在stl

+1

第一部分是錯誤的。你不會因爲沒有使用模板參數而得到編譯錯誤,這是完全合法的,甚至有一些使用情況。 –

1

使用is_base_of功能一般,在C++中,你只想用:

template<class T> 
class MyClass 

你不需要說什麼就像extends OtherClass

這裏的解釋:

在C++和Java中,當你訪問對象的方法或字段,編譯器必須確保靜態類型的對象表達式的支持方法或字段,或者它將無法編譯。

在Java中,泛型類和方法只編譯一次。當編譯泛型類或方法時,不知道什麼類型的參數(如T)是或者可以是。因此,必須使編譯器允許訪問Object未提供的方法和字段。具有綁定T extends OtherClass的原因是因爲在MyClass某處,它嘗試訪問由OtherClass提供的T類型表達式上的方法或字段。因此這個界限允許編譯器進行類型檢查併成功編譯。相反,在C++中,對於每個不同的類型參數(稱爲模板的每個「實例化」),模板化類和方法都會編譯一次,就好像編譯器複製並粘貼模板代碼的副本並將實際在代碼中爲每個出現的T鍵入參數。因此,編譯模板類或方法時,會確切知道T是什麼類型。與Java一樣,綁定的規範是不必要的,因爲編譯器可以直接檢查T是否支持給定的方法或字段。如果TOtherClass的子類型,它將成功編譯。如果T不是OtherClass的子類型,則可能是它沒有該名稱的方法或字段,並且即使它具有該字段,它也可能沒有正確的類型,因此它可能無法編譯。它基本上是鴨子打字。

(這是不可能的,但有可能,你有一個不同的,不相關的類型,它是不是OtherClass一個亞型,也有方法,且名稱相同的字段和類型與在MyClass用於OtherClass的那些,並且如果你嘗試使用該類型來參數化MyClass,編譯器不會抱怨它,但是,對於這樣的類型來說,它可能是糟糕的設計,並且不太可能會意外地在錯誤中使用這種類型)

相關問題