[boolan]这周的C++笔记,注意点

来源:互联网 发布:优麒麟和ubuntu 编辑:程序博客网 时间:2024/05/17 01:05

1.STL的算法,主要是通过迭代器来操作容器,但是并不是任意容器的迭代器都可以直接使用的,比如说要使用快速排序的话,迭代器的移动必须要内存上的连续,也就是random_access_iterator,可以看到,源码虽然是模板函数,但是在名称上提示了要使用random_access_iterator

 template<typename _RandomAccessIterator>    inline void    sort(_RandomAccessIterator __first, _RandomAccessIterator __last)    {      typedef typename iterator_traits<_RandomAccessIterator>::value_type_ValueType;      ......        if (__first != __last){  std::__introsort_loop(__first, __last,std::__lg(__last - __first) * 2);  std::__final_insertion_sort(__first, __last);}    }

当然像链表,队列这种结构也可以排序,这些容器自己就提供了排序sort()方法(不是stl的algorithm),但是显然如果迭代器不支持随机访问的话,肯定会慢一点。STL的算法虽然是一种泛化的设计,但是为了在特定的情况下追求更高的效率,它会判断各种情况去特化,尽可能效率更高。其中,通过iterator种类来判断是否特化就是一种常见的手段,还有就是通过type_trais来判断:

2.仿函数

一种类或结构,通过重载操作符()去模仿函数的行为,例如:

template <class T>struct plus : public binary_function<T,T,T> {    T operator()(const T& x,const T& y) { return x+y; }};

挺神奇的,为什么要费心思做这么麻烦的事,因为STL的算法algorithm要用:

template <typename Iterator, typename Cmp>algorithm(Iterator I1,Iterator I2,Cmp cmp) {    ......}

算法要实现“某些”操作必须要把这个操作(Cmp)穿进去,像刚才的例子,想做加法不能直接把加号传进去,所以要用到仿函数。

注意到仿函数在设计的时候继承了STL的binary_function类,表示这是一个二元函数,有两个参数,同样STL里还有unary_function()表示只有一个参数的函数操作,例如取反(!)。

如果只是小程度地使用仿函数,即使不继承binary_function,使用上也不太会有问题,不过如果要设计一种能和STL水乳交融的仿函数的话,这个是一定要继承的,因为STL的一些其他部件(例如适配器)要正确使用的话,需要知道一些额外的信息才能正常使用,而这些信息就在binary_function这些东西里:

template<typename _Arg1, typename _Arg2, typename _Result>    struct binary_function    {      /// @c first_argument_type is the type of the first argument      typedef _Arg1 first_argument_type;       /// @c second_argument_type is the type of the second argument      typedef _Arg2 second_argument_type;      /// @c result_type is the return type      typedef _Result result_type;    };

3.适配器

个人理解功能上类似一种转换器,例如原API借口比较难使用,通过适配器外面套一层,可以用起来方便点,或者“稍微”改变/优化一下原API的功能,例如bind可以再外层绑定函数的参数。同理,除了函数适配器以外,STL还有高深的迭代器适配器,典型的就是reverse_itertator,insert_iterator。它在内部重载++等操作,直接改变了这种操作原本的行为,实现了迭代器的逆向移动和插入操作,这样做的好处是,Algorithm部分可以不用做修改,但是通过适配器的介入,内部进行了完全不同的操作,实现了不同种类的迭代器的,同一种算法效果


0 0