Bjarne:为什么不能为模板参数定义约束?

Bjarne:为什么不能为模板参数定义约束?,第1张

Bjarne:为什么不能为模板参数定义约束?,第2张

可以,而且方法很简单,很通用。

看看这个:

template
void draw _ all(Container & c)
{
for _ each(c . begin(),c.end(),mem _ fun(& Shape::draw));
}

如果存在类型错误,它可能发生在相当复杂的for_each()调用过程中。比如容器的元素类型是int,我们会得到一个与for_each()相关的模棱两可的错误(因为我们不能在一个int值上调用Shape::draw的方法)。

为了提前发现这个错误,我这样写道:

模板
void draw _ all(Container & c)
{
Shape * p = c . front();//只接受Shape*s
的容器for_each(c.begin()、c.end()、mem _ fun(& Shape::draw));
}

对于现在大多数编译器来说,中间变量p的初始化会触发一个容易理解的错误。这种技巧在许多语言中都很常见,在所有的标准创建中都必须这样做。在成品的代码中,我可能会写出这样的东西:

模板

void draw_all(容器& c)
{
typedef typename容器::value _ type T;
Can _ copy();//对于_each(c.begin(),c.end(),mem_fun(&Shape::draw)),只接受Shape*s
的容器;
}

所以很明显我在建立一个断言。Can_copy模板可以定义如下:

模板结构Can_copy {
静态void约束(T1 a,T2 b){ T2 c = a;b = a;}
Can_copy() { void(*p)(T1,T2)= constraints;}
};

Can_copy(运行时)检查T1是否可以分配给T2。Can_copy检查t是Shape*类型,还是指向从Shape类公开继承的类的对象的指针,或者是由用户转换为Shape*类型的类型。请注意,此定义已被简化为最小值:

一行命名要检查的约束和要检查的类型。

一行列出了要检查的指定约束(constraints()函数)。

一行代码提供了触发检查的方法(通过构造函数)。

注意,这个定义在本质上是相当合理的:

你可以不用声明或者复制变量来表达一个约束,这样约束编写者就不用去想象变量是如何初始化的,对象是可以复制还是销毁,等等。(当然,当需要约束来检查这些属性时除外。)

使用当前的编译器,不需要为约束生成代码。

和使用约束,而不使用宏。

当约束失败时,编译器会给出一个可接受的错误消息,包括“constraints”这个词(给用户一个提示),约束的名称,以及导致约束失败的详细错误(例如,“无法用double*”初始化Shape*)。

位律师回复
DABAN RP主题是一个优秀的主题,极致后台体验,无插件,集成会员系统
白度搜_经验知识百科全书 » Bjarne:为什么不能为模板参数定义约束?

0条评论

发表评论

提供最优质的资源集合

立即查看 了解详情