避免使用vector<bool>
12.永不建立auto_ptr的容器,当你向set中插入一个新元素时,set::insert必须可以判断那个元素的值是否已经在set中了。
优先选择成员函数(就像set::find)而不是非成员兄弟(就像:find)
13为指针的关联容器指定比较类型
如果你想要string*指针以字符串值确定顺序被储存在set中,你不能使用默认仿函数类less<string*>.你必须改为写你自己的比较仿函数类,它的对象带有string*指针并按照指向的字符串值来进行排序。就像这样:
Struct StringPtrLess:
Public binary_function<conststring*,const string*, bool>
{
Bool operator()(const string* ps1, conststring* ps2)const
{
Return *ps1 < *ps2;
}
}
Typedef set<string*, StringPtrLess> StringPtrSet;
StringPtrSet ssp;
For(StringPtrSet::const_iterator I =ssp.begin(); i!= ssp.end(); ++i)
{
Cout<<**i<<endl;
}
14.永远让比较函数对相等的值返回false;
15.避免原地修改set和multiset的键
16.考虑用有序vector代替关联容器
17.当关乎效率时应该在map::operator[]和map-insert之间仔细选择
18.remove并不“真的”删除东西,因为它做不到
如果你真的要删除东西的话,你应该在remove后面接上erase。你要erase的元素很容易识别。他们是从区间的“新逻辑终点”开始持续到区间真的终点的原来区间的元素,要除去那些元素,你要做的所有事情就是用那两个迭代器调用erase的区间形式。因为remove本身很方便地返回了区间新逻辑终点的迭代器,这个调用很直截了当:
Vector<int> v;
v.erase(remove(v.begin(),v.end(),99),v.end());
cout<<v.size();
把remove的返回值作为erase区间形式第一个实参传递很常见,这是个惯用法。事实上,remove和erase是亲密联盟,这两个整合到list成员函数remove中。这是STL中唯一名叫remove又能从容器中除去元素的函数:
List<int> li;
li.remove(99);
19.提防在指针的容器上使用类似remove的算法
20.尽量用算法调用代替手写循环;
21.尽量用成员函数代替同名的算法
大多数情况下,你应该用成员函数代替算法。这样做有两个理由。首先,成员函数更快。其次,比起算法来,它们与容器结合得更好(尤其是关联容器)。那是因为同名的算法和成员函数通常并不是一样的。
22把count用来作为是否存在的检查if(count(lw.begin(),lw.end(),w)!= 0)…
把find用来作为检查的值在哪if(find(lw.begin(),lw.end(),w) != lw.end())…
List<Widget>::iterator I =find(lw.begin(),lw.end(),v)
If(I != lw.end()){//找到了,i指向第一个}
Binary_searchz只返回一个bool:这个值是否找到了。Binary_search回答这个问题:“它在吗?”它的回答只能是是或者否。
当你用lower_bound来寻找一个值的时候,它返回一个迭代器,这个迭代器指向这个值的第一个拷贝(如果找到的话)或者可以插入这个值的位置(如果没找到)。因此lower_bound回答这个问题:“它在吗?如果是,第一个拷贝在哪里?如果不是,它将在那里?”
Vector<Widget>::iterator I =lower_bound(vw.begin(),vw.end(),w);
If(I != vw.end() && *I == w)//保证i指向一个对象
{
}
22.vector<double> v;
Sort(v.begin(),v.end(),greater<double>());
或者
Inline bool doubleGreater(double d1, doubled2)
{
Return d1 > d2;
}
Sort(v.begin(),v.end(),doubleGreater);
23.避免产生只写代码