您的位置:首页 > Web前端

Effective STL 20 Specify comparison types for associative containers of pointers

2017-08-28 11:11 447 查看
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());
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: