《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;
}

 

 

 

 

posted @ 2013-05-07 15:29  轻典  阅读(241)  评论(0编辑  收藏  举报