C++/CLR泛型与C++模板的对比(2)
}; 在上面的例子中,出现了三个约束子句,同时指定了接口类型和一个类类型(在每个列表的末尾)。这些约束是有额外的意义的,即类型参数必须符合所有列出的约束,而不是符合它的某个子集。我的同事Jon Wray指出,由于你是作为泛型的作者来扩展操作集合的,因此如果放松了约束条件,那么该泛型的用户在选择类型参数的时候就得增加更多的约束。
T1、T2和T3子句可以按照其它的次序放置。但是,不允许跨越两个或多个子句指定某个类型参数的约束列表。例如,下面的代码就会出现违反语法错误:
generic <class T1, class T2, class T3>// 错误的:同一个参数不允许有两个条目
where T1 : IComparable, ICloneable
where T1 : Image
public ref class Compositor
{// ...
}; 类约束类型必须是未密封的(unsealed)参考类(数值类和密封类都是不允许的,因为它们不允许继承)。有四个System名字空间类是禁止出现在约束子句中的,它们分别是:System::Array、System::Delegate、 System::Enum和System::ValueType。由于CLI只支持单继承(single inheritance),约束子句只支持一个类类型的包含。约束类型至少要像泛型或函数那样容易访问。例如,你不能声明一个公共泛型并列出一个或多个内部可视的约束。
任何类型参数都可以绑定到一个约束类型。下面是一个简单的例子:
generic <class T1, class T2>
where T1 : IComparable<T1>
where T2 : IComparable<T2>
public ref class Compositor
{// ...
};
约束是不能继承的。例如,如果我从Compositor继承得到下面的类,Compositor的T1和T2上的Icomparable约束不会应用在BlackWhite_Compositor类的同名参数上:
generic <class T1, class T2>
public ref class BlackWhite_Compositor : Compositor
{// ...
};
generic <class T1, class T2>
where T1 : IComparable<T1>
where T2 : IComparable<T2>
public ref class BlackWhite_Compositor : Compositor
{// ...
}; 包装
你已经看到了,在C++/CLI下面,你可以选择CLR泛型或C++模板。现在你所拥有的知识已经可以根据特定的需求作出明智的选择了。在两种机制下,超越元素的存储和检索功能的参数化类型都包含了每种类型参数必须支持操作的假设。
使用模板的时候,这些假设都是隐含的。这给模板的作者带来了很大的好处,他们对于能够实现什么样的功能有很大的自由度。但是,这对于模板的使用者是不利的,他们经常面对某些可能的类型参数上的没有正式文档记载的约束集合。违反这些约束集合就会导致编译时错误,因此它对于运行时的完整性不是威胁,模板类的使用可以阻止失败出现。这种机制的设计偏好倾向于实现者。
使用泛型的时候,这些假设都被明显化了,并与约束子句中列举的基本类型集合相关联。这对泛型的使用者是有利的,并且保证传递给运行时用于类型构造的任何泛型都是正确的。据我看来,它在设计的自由度上有一些约束,并且使某些模板设计习惯稍微难以受到支持。对这些形式约束的违反,无论使在定义点还是在用户指定类型参数的时候,都会导致编译时错误。这种机制的设计偏好倾向于消费者。
顶(0)
踩(0)
上一篇:类——C++面向对象编程的基石
下一篇:C++中union的应用剖析
- 最新评论
