我正在研究一个C#项目,发现自己试图在C ++中重现一个常见的模式,但到目前为止还没有。我正在尝试做的一个例子(在C ++中):
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#中具有某种类似的能力可以帮助我避免大量重复的代码,但我不想传递所有类型(ProductItem
,ProductItemType
,以及更多我一直都在排除简单性。
答案 0 :(得分: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问题。