• 《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;
    }
  • 相关阅读:
    SQL SERVER 实现多个数据库之间表的联系,利用临时表枚举表中行数据
    [CCF CSP]201909-2 小明种苹果(续)
    Anaconda 安装 Python 库(MySQLdb)
    [CCF CSP]201903-4 消息传递接口
    [CCF CSP]201609-4 交通规划
    2019年12月CSP考试第三题化学方程式解法
    Leetcode.94.二叉树的中序遍历
    GENIA命名实体数据集解析代码
    git添加新用户
    C#语言 十大经典排序算法动画与解析!(动态演示+代码)(java改写成C# )
  • 原文地址:https://www.cnblogs.com/tianyajuanke/p/3064860.html
Copyright © 2020-2023  润新知