《C++标准程序库》 第4章 通用工具

第1~3章 略

 

std::pair 是一个 struct ,定义于 bits/stl_pair.h 文件中,被包含进 <utility> 头文件中。

std::make_pair(42,'@')  //相当于 std::pair<int,char> (42,'@')

std::pair<int,int> p = std::make_pair(42,3.3);   //42,3

任何函数需要返回两个值,必须使用 pair; 标准程序库中 map 和 multimap 容器的元素型别也是 pair。

 

std::auto_ptr<int> p(new int(3));  定义于 backward/auto_ptr.h 文件中,被包含进 <memory>头文件中。

auto_ptr 要求一个对象只有一个拥有者,绝对不应该出现多个 auto_ptr 拥有一个对象的情况。如:

std::auto_ptr<int> p1(p);  

std::cout<<*p1<<std::endl;  //OK

std::cout<<*p<<std::endl;   //段错误

auto_ptr 的 copy 构造函数 和 assignment 操作符会将对象拥有权交出去。

程序员需要自己来保证那个”失去了所有权、只剩下一个 null 指针“的原 auto_ptr 不会再次被进行提领动作。

将 auto_ptr 作为函数参数或函数返回值,一定要特别注意所有权问题。比如:

std::auto_ptr<int> p(new int(42));

fun(p);    //p的所有权已经转交出去

*p = 18;  //error   

不要试图使用 pass by reference 方式来传递 auto_ptr ,因为你根本无法预知拥有权是否被转交。

如果用 const 来修饰一个 auto_ptr ,并非意味着不能更改它拥有的对象,而是意味着你不能更改 auto_ptr 的所有权。

auto_ptr 的注意点:

1、auto_ptr 之间不能共享拥有权,一个 auto_ptr 不能指向另一个 auto_ptr 所拥有的对象。

2、并不存在针对 array 而设计的 auto_ptr,因为 auto_ptr 是通过 delete 而不是 delete [] 来释放对象的。

3、它的通用性不强,它不是引用计数型指针。

4、auto_ptr 不满足 STL 容器对元素的要求,比如拷贝和赋值动作。

C++11标准已经废弃了 auto_ptr ,取而代之的是  unique_ptr。

 

数值极限(Numeric Limits)是与平台有关的,C++标准库通过 template numeric_limits 提供这些极值,取代传统C语言所采用的预处理器常数。前者定义于头文件 <limits> 中,后者整数常数定义于 <climits> 和 <limits.h>,浮点常数定义于 <cfloat> 和 <float.h> 中,推荐使用前者,有更好的型别安全性。

numeric_limits 中提供了通用性的 template 和特化版本,如:

template <class T> class numeric_limits {...};

template <> class numeric_limits<int> {...};

使用示例如下:

#include <iostream>

#include <limits>

#include <string>



int main()

{

    std::cout<<std::numeric_limits<int>::is_specialized<<std::endl; //是否有极值

    std::cout<<std::numeric_limits<int>::max()<<std::endl;

    std::cout<<std::numeric_limits<int>::min()<<std::endl;

    std::cout<<std::numeric_limits<std::string>::is_specialized<<std::endl;

    std::cout<<std::numeric_limits<std::string>::max()<<std::endl;  //Error!

}

 

 在两个值之间挑选较大值和较小值的辅助函数,定义于 <bits/stl_algobase.h> ,被包含进 <algorithm> 头文件。源码如下:

template<typename _Tp> 

inline const _Tp& 

max(const _Tp& __a, const _Tp& __b) 

{

  // concept requirements

  __glibcxx_function_requires(_LessThanComparableConcept<_Tp>)

  //return  __a < __b ? __b : __a;

  if (__a < __b) 

return __b; 

  return __a; 

}



template<typename _Tp, typename _Compare>

inline const _Tp&

max(const _Tp& __a, const _Tp& __b, _Compare __comp)

{

  //return __comp(__a, __b) ? __b : __a;

  if (__comp(__a, __b))

return __b;

  return __a;

}

min 函数实现类似,略。使用示例如下:

#include <iostream>

#include <algorithm>



struct User

{

    User(int _id):id(_id){}

    bool operator<(const User& user2) const  //这里只需要实现 operator< 即可

    {   

        return id < user2.id;

    }   

    int id; 

};



bool compareUser(User user1,User user2)

{

    return user1.id < user2.id;  //要返回 第一个参数 < 第二个参数的 bool 值

}



int main()

{

    User user1(3),user2(2);

    std::cout<<std::max(user1,user2).id<<std::endl;

    std::cout<<std::max(user1,user2,compareUser).id<<std::endl;

}

 

有四个比较操作符的 template functions ,分别定义了 !=, >, <=, >= ,它们都是利用操作符 == 和 < 完成的,定义于头文件 <utility>,位于命名空间 std::rel_ops;

namespace std

{

    namespace rel_ops

    {

        template <class T>

        inline bool operator!=(const T& x, const T& y)

        {

            return !(x == y);

        }



        template <class T>

        inline bool operator>(const T& x, const T& y)

        {

            return x < y;

        }



        template <class T>

        inline bool operator<=(const T& x, const T& y)

        {

            return !(y < x);

        }



        template <class T>

        inline bool operator>=(const T& x, const T& y)

        {

            return !(x < y);

        }

    }

}

只需要定义 < 和 == 操作符,然后 using namespace std::rel_ops; 上述四个操作符就自动获得了定义。

#include <iostream>

#include <utility>



struct User

{

    User(int _id):id(_id){}

    bool operator==(const User& user) const

    {   

        return id == user.id;

    }   

    bool operator<(const User& user) const

    {   

        return id < user.id;

    }   

    int id; 

};



int main()

{

    using namespace std::rel_ops;

    User user1(3),user2(4);

    std::cout<<(user1>user2)<<std::endl;

}

 

 

 

 

你可能感兴趣的:(C++)