Effective STL 20 Specify comparison types for associative containers of pointers

define a set

set<string*>ssp;

// is shorthand for this:
set<string*, less<string*> > ssp;

// to be completely accurate, it's shorthand for
set<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 pinter
for_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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值