等价于C++';s模板编程中使用的typedefs/别名

本文关键字:typedefs 别名 编程 C++ 等价于 | 更新日期: 2023-09-27 18:01:12

我正在做一个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#中拥有某种类似的能力可以帮助我避免大量重复的代码,但我不想一直传递所有类型(ProductItemProductItemType,以及为了简单起见我排除的更多类型(。

等价于C++';s模板编程中使用的typedefs/别名

很难准确说出您的用例是什么,因为您还没有提供这样的示例:

然后,使用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问题。