2011-10-10 110 views
2

對不起,這個愚蠢的問題,但我很新的C++。C++模板類和返回類型作爲約束

我在我的項目中有一個叫做AlertInfoBase的基類。它有幾十個子類。現在我想要一個類模板,它將有一個方法filter()。此方法將始終返回對AlertInfoBase的引用。代碼如下:

template <class T> 
class AlertInfoFilter 
{ 
public: 
    AlertInfoFilter() { } 
    AlertInfoBase & filter(T & alertInfo) 
    { 
     return alertInfo; 
    } 
}; 

正如您所看到的,方法過濾器只是返回傳遞的參數。我的目標是使用模板專門化創建filter()的替代實現,但這不是我現在的問題/問題。 我面臨的奇怪的事情是,當我將一個類的實例傳遞給filter()(從AlertInfoBase繼承而來)時,一切都按預期工作。它返回相同的引用,但是當我傳遞一個不實現AlertInfoBase的類的實例時,該項目不會編譯。其實這是我想要的那種行爲,但有些澄清爲什麼發生這種情況會很好。編譯器是否足夠聰明地猜測,由於返回類型而使用不正確的參數填充方法?

謝謝

P.S.我正在使用MinGW編譯器。

回答

5

您可以將模板視爲代碼生成機制。模板的特定實例在大多數情況下與手動編寫的代碼完全相同,只需在適當的位置替換模板參數即可。在你的榜樣,如果你實例化AlertInfoFilterstd::string(如不從AlertInfoBase繼承一個類的實例),然後將下面的代碼是(約)產生:

class AlertInfoFilter_string 
{ 
public: 
    AlertInfoFilter_string() { } 
    AlertInfoBase & filter(std::string & alertInfo) 
    { 
     return alertInfo; 
    } 
}; 

顯然,這不應該編譯。

4

是的,編譯器確實足夠聰明,知道這一點。當T從AlertInfoBase下降並且無法在其他情況下將T轉換爲返回類型時,它使用從子類到基類的隱式轉換。

它也可以與一個在不相關的類中實現operator AlertInfoBase&的類一起使用,但這隻會增加混淆,所以我不建議這樣做。

+0

我會非常感興趣你將如何實現該操作符:)我可以想出一些有意思的方法,但除非類型爲「is-a」或「has-a」AlertInfoBase,否則似乎並不適合:)(請注意,這是我在'答案'中暗示'可轉換爲'而不是'派生自') – sehe

+0

它也適用於共享單個AlertInfoBase的墊片。 – MSalters

0

filterT作爲輸入並將其轉換爲AlertInfoBase。如果T現在是不是AlertInfoBase的子類的類型,並且不提供轉換,則無法編譯該程序。

0

實際上,編譯器做了一些接近代碼的事情,用T代替實際參數並編譯模板。對於您在程序中使用的每個不同的T,都會發生一次。

當你通過例如。一個int,你得到:

class AlertInfoFilter 
{ 
public: 
    AlertInfoFilter() { } 
    AlertInfoBase & filter(int & alertInfo) 
    { 
     return alertInfo; 
    } 
}; 

顯然不能編譯。