STL实用(146)

最近懈怠了STL,弄得都要翻资料了,赶紧弄点笔记:


建议

  • vector,等容器指针,真心是坑;要写就一定要保证,所有复制,赋值,创建,删除,自己写,所有的stl函数要留意点,比如remove这种移动函数。不然,用默认函数就特么操作指针,后面简直叫妈妈!!!

  • vector比deque多了capacity(能容纳的元素数量,就是开辟内存),reserve。可以看出vector的虚拟预定义分配。
    vector对内存的处理是开辟后,clear并不释放,而是在析构函数上释放;所以要动态回收大多内存就要用swap来。vec.swap(vector());注意这段代码只能和clear连用,因为它同样能清空容器数据。

  • 容器指针,老是需要自己写新函数,并自己调用它。所以STL提供智能指针来解决问题.

    Effective stl指出了几个问题:

    1、auto_ptr不能共享所有权

    2、auto_ptr不能用数组初始化

    3、auto_ptr不能作为容器成员

    4、不能通过赋值操作来初始化auto_ptr

    5、不要把auto_ptr放入容器。

    shared_ptr就解决了1个问题而已。
代码演示++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
typedef vector<int*> v_pint;
auto_ptr<v_pint> auto_p(new v_pint/*, 这里可以指定析构函数*/);
auto_p->push_back(new int(1));
auto_p->push_back(new int(2));
auto_p->push_back(new int(3));
auto_p->push_back(new int(4));
v_pint auto_pt;
auto_pt.push_back(new int(5));
auto_pt.push_back(new int(6));
auto_pt.push_back(new int(7));
bool bequal = std::equal(auto_pt.begin(), auto_pt.end(), auto_p->begin());//这里比较的是指针,注意。永远是错误
pair<v_pint::iterator, v_pint::iterator> it = std::mismatch(auto_pt.begin(), auto_pt.end(), auto_p->begin());//第一个是auto_pt第二个是auto_p
//干脆下面开写各种函数
struct dd
{
int d_;
int a_;
bool operator==(const dd& d) {
if (d.a_ == a_ && d.d_ == d_) {
return true;
}
return false;
}
static bool bequal(dd*& d1, dd*& d2) {
if (d1->a_==d2->a_&&d1->d_==d2->d_) {
return true;
}
return false;
}
static dd* copydata(dd* p) {
dd* rp = new dd;
rp->a_ = p->a_;
rp->d_ = p->d_;
return rp;
}
};
template<typename T>
struct RemoveTranData :
public std::binary_function<T*&, T* , void>
{
void operator ()(T*& p, T*) const {
if (*T == *p) {
DEL_P(p);
}
}
};
template<typename T>
struct RemoveAllTranData :
public std::unary_function<T*, void>
{
void operator ()(T* p) const {
if (p != NULL) {
delete p;
p = NULL;
}
}
};
int _tmain(int argc, _TCHAR* argv[])
{
typedef vector<dd*> v_pint;
v_pint v_int;
v_int.push_back(new dd{2,3});
v_int.push_back(new dd{3,4});
v_int.push_back(new dd{4,5});
v_int.push_back(new dd{6,7});
dd* pt = new dd{ 6, 7 };
v_pint::iterator i = find_if(v_int.begin(), v_int.end(), bind2nd(mem_fun(&dd::operator==), *pt));//指针的find
bool b = std::equal(v_int.begin(), v_int.end(), v_int2.begin(), (&dd::bequal));//指针的比较equl,最好更新成成员函数,待修改吧
v_int3.resize(v_int2.size());//注意这里哟
std::transform(v_int2.begin(), v_int2.end(), v_int3.begin(), (&dd::copydata));//指针的复制, 想用上面find那种类型来着,发现复制错误了!!!</br>
//值得一提的是stl虽然有copy,但是却对容器指针依旧只是指针的赋值;而且使用前必须用resize来分配大小后再使用。
//copy_if却是c++11的东西了要配合lamda了;copy_if(arr.begin(), arr.end(), back_inserter(res)//res.begin(),[](const int i) { return i == 5 || i == 7; });
//copy_backward是copy的逆向复制
for_each(_doorVec.begin(), _doorVec.end(), mem_fun_ref(&Door::open));//留个思想,以后封装用
system("pause");
return 0;
}

2

后面就给点有用的东东++
1
2
3
4
5
6
7
8
9
10
11
12
13
template <class forwardItr,class Type>
void replace(forwardItr first, forwardItr last,const Type& oldValue const Type& newValue);
template <class forwardItr, class unaryPredicate,class Type>
void replace_if(forwardItr first, forwardItr last, unaryPredicate op,const Type& newValue);
template <class inputItr,class outputItr,class Type>
outputItr replace_copy(inputItr first1, inputItr last1, outputItr destFirst,const Type& oldValue, const Type& newValue);
template <class inputItr,class outputItr, class unaryPredicate>
outputItr replace_copy_if(inputItr first1, inputItr last1, outputItr destFirst, unaryPredicate op,const Type& newValue);

3

首先可供查找的算法大致有count,find,binary_search,lower_bound,upper_bound,equal_range。带有判别式的如count_if,find_if或者binary_search的派别式版本,其用法大致相同

4

参考:http://blog.csdn.net/sdhongjun/article/details/4517325/

++
1
2
3
4
5
6
7
8
9
10
11
//stdext::hash_map等都比map高效多了
struct less: public binary_funtion<const char, const char*, bool>
{
result_type opeator()(const first_argument_type& _left, const second_argument_type _right) const {return (_wcsicmp(left, right) < 0 ? true : false);
}
}//简直太装逼了,result_type first_argument_type second_argument_type。悬浮一看,就特么是前面 const char* bool,只是被内部转换了一些。。。。真装逼。。。。
//这个是hash_map的比较,因为键不能默认字符,必须自己写比较。
stdext::hash_map<cstring, TDATA1, stdext::hash_compare<const whcar_t*, less>>
//参考

5

参考来自:stackoverflow :c++ unordered_map using a custom class type as the key

//std::tr1::unordered_map无序的高效map,貌似虐爆hash_map和map
//boost却要写个hash_value
struct KeyHasher
{
    std::size_t operator()(const CString& k) const
    {
        retrun (hash<wstring>()(k.GetString()));
    }
}

6

151对stl所有map和mfc的map做了比较,请看链接

// //