2016-08-05 67 views
0

我正在研究一個C#項目,並發現自己試圖在C++中重現一個常見模式,但到目前爲止一直未能。什麼,我試圖做(在C++)的一個例子:等效的C++的typedefs /別名在模板編程中使用

enum ProductItemTypes { 
    Product, 
    Family, 
    SubFamily, 
    Department 
}; 

class ProductItem : PanelItem { 
public: 
    using item_type_t = ProductItemTypes; 
    ... 
}; 

enum PaymentItemTypes { 
    Group, 
    Valued, 
    NotValued, 
    Balance 
}; 

class PaymentItem : PanelItem { 
public: 
    using item_type_t = PaymentItemTypes; 
    ... 
}; 

有跡象表明,從PanelItem繼承和擁有自己的item_subtype_t不同類別。 然後,使用PanelItem的類,可以知道相應的項目類型並一般工作。在C#中有某種類似的能力可以幫助我避免大量的重複代碼,但我不想通過所有類型(ProductItemProductItemType,以及我爲簡單排除的一些內容)每時每刻。

+1

@Barry,我添加了[標籤:C++],因爲您必須能夠閱讀該源代碼。 – Sinatr

+0

爲什麼不能:template class Panel { public: .... }; Then Panel foo; 最終你可以定義一個如上所述的類型。 – nosbor

+0

@nosbor是的,面板部分並不重要,重要的部分是'ProductItem'中的'item_subtype_t',因爲不同的'PanelItem'在那裏有不同的類型定義 –

回答

2

很難告訴你的使用情況是在這裏正是因爲你沒有提供這樣一個例子:

然後,使用PanelItems類,就可以知道相應的項目類型和一般工作。

直接使用PanelItems將無法​​做到這一點。周圍的唯一方法是,如果類是一個模板類,花類直接(我猜是你真正的意思是什麼發生):

template<class T> 
class Foo 
{ 
public: 
    using item_type_t = typename T::item_type_T; 
} 

你不是要能夠用C#來做到這一點。雖然語法上的泛型和模板看起來非常相似,但它們是兩個截然不同的野獸。對於每個不同的具體類型替換,C++模板都會被編譯一次。這也是允許SFINAE發生的原因。基本上每當編譯器看到模板的用法時,它就會替換類型參數並嘗試重新編譯類或方法。另一方面,C#的泛型只能被編譯一次,並且對於類型參數是不可知的。這就是在C#中存在通用約束的原因:它允許您爲編譯器提供更多關於它將要處理的類型的知識。這也意味着C#沒有SFINAE的概念,因爲編譯器沒有實際的替換。

我的意見是,你目前的做法是漏。基本上不同的item_type_t類型是派生類的實現細節,這些類的用戶必須知道該類型是爲了正確使用類型。對我來說,這是破解封裝,而C++只是提供了一種機制,讓你通過隱藏程序員的類型知識來避開這種泄漏,並且只需要編譯器真正知道它。

沒有關於您正在嘗試做什麼的更多詳細信息,很難對其他方法提出任何建議。我相當確信有一個可以清楚處理您的問題的替代設計,但現在這是一個XY問題。

+0

你是對的,而且你幫助我看到我對自己目前的想法過於關閉,打開一個不同的,更合適的想法。謝謝! –

+0

另外,感謝泛型與模板的洞察力! –

+0

@FedericoAllocati沒問題,我與很多從C++轉換到C#開發的開發人員一起工作,泛型與模板之間的關係是其中的一個難點。在C#中進行開發與C++明顯不同,想要嘗試將模式從一個模式轉移到另一個模式是很常見的,但這幾乎總是一個錯誤(通常不可能如此處所見)。 – Kyle