快速业务通道

What are you,Anyway?

作者 佚名技术 来源 程序设计 浏览 发布时间 2012-06-29
rcentage>() << endl;

最后,我们可以修改接口来使用Monostate。

class GSNamedMonostate {
public:
template <typename N>
void set( const typename N::Type &val ) {
// This const_cast is actually safe,
// since we are always actually getting
// a non-const object. (Unless N::Type is
// const, then you get a compile error here.)
const_cast<typename N::Type &>(get()) = val;
}
template <typename N>
const typename N::Type &get() const {
static typename N::Type member;
return member;
}
};

这是原型模式(Protopattern)吗?

其实,像我们刚刚开始提到的一样,这是搜索技术。同样,我们没有权利调用这样的模式。一个设计模式是包装了成功的实际成果的。这个"protopattern"通常应用在上下文中可以察觉的技术,因此,不能被应用于更加广泛的“pattern”软件中。由于我们不能指出它的成功之地方,所以,我们只能尽量扩展monostate这个模式。

Template Names in Templates

让我们回到分析模板的编译器问题上来吧。编译器分析的难题,不仅只有嵌入type names,而且,我们还常常见到嵌入 template names 类似的问题。调用一个类,或类模板必须有一个这样的成员。这个成员是一个类,或模板函数。

例如:一个使用模板成员函数的扩展Monostate可以按需要这样初始化:

typedef Name<int,86> grossAmount;
typedef Name<double,007> percentage;
GSNamedMonostate nm1, nm2;
nm1.set<grossAmount>( 12 );
nm2.set<percentage>( nm1.get<grossAmount>() + 12.2 );
cout << nm1.get<grossAmount>() * nm2.get<percentage>() << endl;

在上面的代码中,编译器在检查模板get不会碰到任何困难。 其中,nm1和nm2是GSNamedMonostate的类型名,编译器可以在类里面查询get和set的类型。

然而,考虑写这样一个优雅的函数:它能够用来移置扩展的Monostate object。

template <typename M>
void populate() {
M m;
m.get<grossAmount>(); // syntax error!
M *mp = &m;
mp->get<percentage>(); // syntax error!
}

又一次,问题出在编译器不知道M足够的信息,除了,知道它是type name外。特别是,如果没有足够的get<>信息的话,编译器会认为它不是type,不是模板名。因此,m.get<grossAmount>()的中括号被解释为大于号,和小于号,而不是模板参数列表。

这种情况下,解决办法是要告诉编译器<>是模板参数列表,而不是其他的操作名。

template <typename M>
void populate() {
M m;
m.template get<grossAmount>(); // OK
M *mp = &m;
mp->template get<percentage>(); // OK
}

是不是不可思议啊,就像分析使用typename一样,这种template特殊的用法,仅在必要的情况下,才能使用。

Hints For Rebinding Allocators

我们也碰到嵌入模板类的同样的分析问题,在STL allocator的实现,就是这样的经典例子。

template <class T>
class AnAlloc {
public:
//...
template <class Other>
class rebind {
public:
typedef AnAlloc<Other> other;
};
//...
};

这个模板类AnAlloc中就有嵌入的name,而这个name本身就是一个模板类。这是使用STL的框架来创建allocators,就像allocators为一个容器用不同的数据类型初始化一样。例如:

typedef AnAlloc<int> AI; // original allocator allocates ints
typedef AI::rebind<double>::other AD; // new one allocates doubles
typedef AnAlloc<double> AD;

凌众科技专业提供服务器租用、服务器托管、企业邮局、虚拟主机等服务,公司网站:http://www.lingzhong.cn 为了给广大客户了解更多的技术信息,本技术文章收集来源于网络,凌众科技尊重文章作者的版权,如果有涉及你的版权有必要删除你的文章,请和我们联系。以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢!

分享到: 更多

Copyright ©1999-2011 厦门凌众科技有限公司 厦门优通互联科技开发有限公司 All rights reserved

地址(ADD):厦门软件园二期望海路63号701E(东南融通旁) 邮编(ZIP):361008

电话:0592-5908028 传真:0592-5908039 咨询信箱:web@lingzhong.cn 咨询OICQ:173723134

《中华人民共和国增值电信业务经营许可证》闽B2-20100024  ICP备案:闽ICP备05037997号