先看看stl 容器set 里面的返回值是怎么弄的.
最近才搞明白为什么set的insert方法真正的用法,简单得连例子都没有.
//注意哦,set 里面的值是不会重复的,也就是说,当在set容器里再插入一个已有的值是没有效果的。
set<int>::_Pairib result = s.insert(30);
result = s.insert( 30 ); //这句注释的话,就打印 new value is 30
if ( result.second )
{
//成功插入
printf ("new value is%d\n", *result.first );
}
else
{
printf ("old value is!%d\n", *result.first );
}
光看源代码,是什么意思,我那时还真是一下子想不明白.
typedef pair<iterator, bool> _Pairib;
如果不是以前看过一本书,讲述如何返回错误值的技巧,以及一大堆背后的考量还真难说.(说了一大堆,比如用异常啦,或者把返回值放在函数参数中啦)
最早使用set时候 只知道返回两个类型,却不明白为什么,还在心理骂过作者,为什么insert没有直接返回iterator?
那个时候也看到Pairib里有个iterator,没有搞明白为什么它会在first里而不在second里,最后项目紧,为了安全,就写成了这样.
s.insert(30);
set<int>::iterator itor = s.find(30);
我想问题的根本原因是名称引起的吧,如果返回值类型是下面这样写的话,估计当时的我也能看得懂吧:
template< typename RET_VALUE, typename ERR_CODE >
struct RET_TEMPLATE
{
RET_VALUE result;
ERR_CODE err;
};
typedef RET_TEMPLATE< iterator, bool > itor_ret_b;
但是为什么他们没有这样做呢?我想应该是当时有现成的pair模板,而为了代码重用的考量吧.
所以RET_TEMPLATE可以不用再写。然而即使是这样,我还是坚持其返回值应该用类似这样的名称 itor_ret_b (有些人水平高了,就容易忽视初学者 @_@ )
话说回来,如果返回值使用这种方式,把错误代码与真正的返回值数据绑定在一起,还真方便哪.
因为这样的话,就可以直接用if判断,也可以直接把返回值做为其它函数的参数传进去了.
就好象用指针可以使用是否为 NULL 来判断其返回值的有效性那么方便.
对哦,iterator也可以返回end的啊,这样不就表明已存在了吗?当时我可能也是这么想的吧.
不过细想一下,也许在已存在一个值的情况下,有人还想要那个值是在哪个位置吧.
毕竟再做一次find真的很影响效率耶.
posted on 2008-12-02 11:13
鹿哥 阅读(594)
评论(0) 编辑 收藏 引用 所属分类:
STL