拯救你的字符串 :种子的外皮

上文http://blog.csdn.net/zy498420/archive/2010/11/09/5998427.aspx提到的“播种”之法需要你手动指定目标类型,稍微还是有点罗嗦(et_seed<std::string>,字母还是挺多的),然而为什么需要指定呢?

原因:如果不指定,最终生成的树可能根本不知道应该转换为何种类型,dest_type 未知。

 

那么把    inline operator binary_op::dest_type () const;

改为       template <typename T>  inline operator binary_op::T() const;不行吗,在“=”的时候自动选择T的类型?

答案:不行。“=”左边的操作对象可能有多种单参数构造函数。以std::string为例,T可以为string也可以为const char*,他们的函数重载决议的地位是平等的,这时候就产生了二义 性,编译器不知道该如何选择。

 

那么我们就一定要一开始就显示指定吗目标类型?

答案:不一定。我们只需要保证第一棵树的构造时,目标类型能被指定。

 

这下问题的本质就出来了:如果种子不携带目标类型信息,而且第一次的操作对象恰好不是目标类型,那么这棵树就永远也没有机会得知目标类型了。

strb =  et_seed<std::string>() + “1234567890"+ str1+ str2 + string("3 ");

如上,第一步et_seed<std::string>() + “1234567890",假设et_seed不携带信息std::string,et_seed<??>() + “1234567890"的结果根本不知道他需要转化成string!

 

那么话又说回来,而且第一次的操作对象是目标类型(我想这其实也是多数情况),那么我们就可以不指定而靠模板函数自动读取操作对象的类型来获得目标类型了。

strb =  et_seed<??>() + str1+“1234567890"+  str2 + string("3 ");

 

我干脆给它取了个新名字any_seed

 

struct any_seed: et_seed<void>{};

然后其它地方修修补补,帮助函数重载决议就搞定了。

 

然而我们不能寄希望用户总是明智的,如果用户strb =  any_seed() + “1234567890"+ str1+ str2 + string("3 ");这样的情况下使用any_seed,生成的树将错误的认为目标类型是char [11]而不是string,直到最后该赋值了编译器才发现不能对char [11]做+=操作,然后口吐莲花,喷出500多K的超长错误信息(最终生成的树类型名字可能长达几个屏幕)......

 

我可不想被用户骂死。

 

终极方案出炉:种子皮

 

template <typename D>

inline _et_private::binary_op<D, any_seed, D> 

any_seeder(const D& arg)

{return _et_private::binary_op<D, any_seed, D> (any_seed(), arg);}

 

strb =   any_seeder(str1)+“1234567890"+  str2 + string("3 ");
strb =   “1234567890" + any_seeder(str1)+  str2 + string("3 ");
哦,我的天,这完全是一个思维的革新,不是吗?我们的改良方式从播种,变为了披上种子皮!!
原来总是需要麻烦的进行"+",这下只需要找准披种子皮的对象!!NICE !mem_func_ref,bind1st的思维方式又一次大放异彩!笔者在写完前一篇文章一小时之内就又有了新灵感,庆祝一下。
其实原来的种子完全可以不开放给用户使用了,种皮完全可以胜任,不过我还是保留了他在私有名字空间之外,留给大家观摩。
附上完整代码:包括any_seed的相关函数重载代码
 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值