2010-10-19 92 views
3

我想創建一個基類,它將被其他對象繼承,以便它們可以存儲在同一個容器中。該基類將包含一個模板化方法,該方法將該函數定義爲用於訪問多線程系統中的緩衝區的setter或getter。我想要做這樣的事,但不知道如何實施Linky。此外,我希望能夠在基地的功能是虛擬的,並在派生類中定義功能,我知道你實際上不能有一個虛擬模板函數,但有沒有一種方法來編碼它的方式它的作用就像虛擬模板功能的概念。下面是我想如何佈局的粗略示例。通過回調調用do_work方法。回調作爲參數傳遞給線程。具有模板函數的繼承類

class A { 
    template<typename R, typename P> 
    virtual R do_work(P param) = 0; 
} 

class B : public A { 
    template<void,int> // declare as setter 
    R do_work(P param){/*do something*/ return R;} 

} 

class C : public A { 
    template<int,void> // declare as getter 
    R do_work(P param){/*do something*/ return R;} 

} 
+0

在鏈接文章中的問題,如果第一個模板參數是「void」,如何做一些不同的事情。我認爲答案是使用'boost :: enable_if'來啓用 - 禁用兩種替代實現中的一種。 - 但不確定,你的問題如何與之相關聯。 – UncleBens 2010-10-19 14:55:57

+0

是否有可能編寫一個測試R是否等於void的宏,如果沒有,則使用此函數(如果不使用具有模板返回類型的函數)。 – Talguy 2010-10-19 15:06:39

+0

另一個問題:你不期待'P'是無效的,給出像'R do_work(void param)'這樣的簽名? – UncleBens 2010-10-19 15:10:59

回答

0

我結束了兩個助手類,一個消費者類和繼承基類的生產者類。基類包含一個枚舉define定義派生類是否是什麼功能。此枚舉值是在基類構造函數調用期間設置的。幫助程序類包含我想要的虛擬do_work函數的適當版本(一個無效w /某些輸入類型和一個返回類型)。當這些對象被放置在容器中時,它們作爲基類被鑄造,並且當它們在適當的通用線程工作者函數中被啓動時,它們被轉移到生產者幫助器類或者消費者幫助器類。

1

您似乎遇到了問題,A是類A中do_work的模板參數:這實際上並不合理。

R未在B或C中的任何位置定義,且您的專業化語法錯誤​​。

do_work不會是多態的,因爲它不是虛擬的,所以如果你有一個A指針集合,它將只會調用A版本,而不是B或C,即使它們是更好的匹配。

+0

對不起,語法錯誤我只是不知道如何實際編碼,所以我只是拋出一些東西一起來最好地說明我最終想要發生的事情。 – Talguy 2010-10-19 14:18:46

0

我所有的使用模板編程的效率和普遍性,但也許你應該有虛函數首先實現這一點。我發現在寫模板版本之前乾淨地工作並糾正是有幫助的。如果你有一個工作的非模板函數這裏

人可能會給你一個更好的答案也。

此外,如果你打算通過回調或指針調用這功能,你就失去了PERF,我認爲你是試圖獲得與基於模板解決方案。

+0

我想我可以做這樣的虛擬無效do_work(void * retrn,void * param)= 0;並在派生類中聲明正確的轉換和功能 – Talguy 2010-10-19 15:03:19

+0

我建議的所有內容是,在應用模板之前,首先查看功能並獲得一些工作。我發現這使得它更容易,我想如果你用一個可行的解決方案編輯你的迴應,你會在這裏得到具體的反饋。 – Rick 2010-10-19 17:27:35

+0

使用void *可能會或可能不是正確的做法,但它可能不是,但如果是這樣的話,您可能希望使其成爲私有的並獲得公共模板函數來執行投射,然後調用該方法。這使得該類對於用戶至少是類型安全的。 – CashCow 2010-10-20 09:42:01