Effective STL 20 Specify comparison types for associative containers of pointers

来源:互联网 发布:触摸屏一体机软件 编辑:程序博客网 时间:2024/06/07 01:19

define a set

set<string*>ssp;// is shorthand for this:set<string*, less<string*> > ssp;// to be completely accurate, it's shorthand forset<string*, less<string*>, allocator<string*> > ssp;

I. specify comparison type

// set tmplate's three parameters is a type. it wants a type that can // internally instantiate to create a function.struct StringPtrLess:    public binary_function<const string*, const string*, bool> {    bool operator()(const string* *ps1, const string* ps2) const {        return *ps1 < *ps2;    }};typedef set<string*, StringPtrLess> StringPtrSet;StringPtrSet ssp;

II. better way to specify comparison

struct DeferenceLess {    template<typename PtrType>    bool operator()(PtrType pT1, PtrType pT2) const {        return *pT1 < *pT2;    }};set<string*, DerefernceLess> ssp;

III. why better?

// explanation (from item 7)class SpecialString:public string {...};template<typename T>struct DeleteObject:    public unary_function<const T*, void> {    void operator()(const T* ptr) const {        delete ptr;    }};deque<SpecialString*> dssp;...for_each(dssp.begin(),                   // Error! Deletion of a derived     dssp.end(), DeleteObject<string>()); // object via a base class pointer                                          // where there is no virtual                                          // destructor// then, move the templatization from DeleteObject to its operator():struct DeleteObject {    template<typename T>    void operator()(const T*ptr) const {        delete ptr;    }deque<SpecialString*> dssp;...// Compilers know the type of pointer being passed to DeletObject::operator(), // so we have them automatically instantiate an operator() taking that type of pinterfor_each(dssp.begin(), dssp.end(), DeleteObject()); // well!

print directly

for (StringPtrSet::const_iterator i = ssp.begin();     i != ssp.end();    ++i) {    cout << *i << endl;

for_each print

void print(const string *ps) {    cout << *ps << endl;}for_each(ssp.begin(), ssp.end(), print);

transform print

// Compilers know the type of pointer being passed to DeletObject::operator(), // so we have them automatically instantiate an operator() taking that type of pinter// when functors of this type are passed a T*, they return a const T&struct Dereference {    template<typename T>    const T& operator()(const T *ptr) const {        return *ptr;    }};transform(ssp.begin(), ssp.end(), ostream_iterator<stirng>(cout, "\n"), Dereference());
阅读全文
0 0
原创粉丝点击