MY_TINY_STL学习

MY_TITY_STL小记

这个链接可能对你有用:小站入口 CSDN入口

/*************************重载运算符****************/
template 
bool operator==(const pair& lhs, const pair& rhs)
{
  return lhs.first == rhs.first && lhs.second == rhs.second;
}

template 
bool operator!=(const pair& lhs, const pair& rhs)
{
  return !(lhs == rhs);
}

template 
bool operator<(const pair& lhs, const pair& rhs)
{
  return lhs.first < rhs.first || (lhs.first == rhs.first && lhs.second < rhs.second);
  //优先比较first
}

template 
bool operator>(const pair& lhs, const pair& rhs)
{
  return rhs < lhs;
}

template 
bool operator<=(const pair& lhs, const pair& rhs)
{
  return !(rhs < lhs);
}

template 
bool operator>=(const pair& lhs, const pair& rhs)
{
  return !(lhs < rhs);
}
/*************************重载运算符****************/

重载==之后,重载!=可以直接利用==。
重载>之后,重载<,<=,>=可以利用>的重载。
如果不是看到源码,我可能会傻乎乎的一个一个写,而不会利用已经重载的运算符,这里给我一个小提示。在类的swap等函数中都用了这种小技巧,第一次见到,还是记录一下。
若问T1,T2是一个类pair无法重载怎么办,这需要在该类中重载运算,这不是pair应该纠结的事情。


template 
void construct(Ty* ptr)
{
  ::new ((void*)ptr) Ty();
}

template 
void construct(Ty1* ptr, const Ty2& value)
{
  ::new ((void*)ptr) Ty1(value);
}	

在construct.h中看到这么一串代码,这里说一下Ty()和Ty(value),你可以认为是两个临时对象。第一个有默认值,第二个有一个初值。
对于类而言,就是一个临时对象。如果是一个数据类型,定义了一个右值对象。
我在编译器下测试如下:

class C
{
    int x,y;
};
void fun(int &&x)
{
    cout<<"右值引用"<

对于构造的临时对象,按道理是不会有内存空间的,但是这里要注意的是,输出的结果是1。
对于int() ,如果输出,值为0,这就是它的默认值。对于字符串,默认值为空串。


iterator.h 简析

源码地址入口

// 五种迭代器类型
struct input_iterator_tag {};
struct output_iterator_tag {};
struct forward_iterator_tag : public input_iterator_tag {};
struct bidirectional_iterator_tag : public forward_iterator_tag {};
struct random_access_iterator_tag : public bidirectional_iterator_tag {};
//不熟知的类 前面的是父类,箭头后面是子类
iterator
has_iterator_cat
iterator_traits_impl(有bool不同的两个版本)->iterator_traits_helper(有bool不同的两个版本)  -> iterator_traits(有偏特化的多个版本)

|   m_bool_constant(type_traits.h文件中的类) -> has_iterator_cat_of     |
|   m_false_type(type_traits.h文件中的类)    -> has_iterator_cat_of		 | 

has_iterator_cat_of -> is_input_iterator
									  -> is_output_iterator
									  -> is_forward_iterator
									  -> is_bidirectional_iterator
									  -> is_random_access_iterator(五个子类)
									  
m_bool_constant -> is_iterator

上面是对类关系的一些提炼,不然要被各种类搞的玩迷宫一样。

在这里举一个例子来说明萃取机:

// 萃取某个迭代器的 value_type
template 
typename iterator_traits::value_type*
value_type(const Iterator&)
{
  return static_cast::value_type*>(0);
}
/*  传进去一个迭代器value_type(const Iterator&),问这个迭代器的value是什么类型啊?
iterator_traits做出解释:   */
template 
struct iterator_traits
{
  typedef random_access_iterator_tag           iterator_category;
  typedef T                                    value_type;
  typedef T*                                   pointer;
  typedef T&                                   reference;
  typedef ptrdiff_t                            difference_type;
};
/*  哦,我知道了,原来是T啊!  */
/*对于typedef可以看成是一问一答的形式,一层一层往上问,最底层的类给出答案,然后一层一层又传到疑问这里。  
typedef A B ,问A的类型,这时候代码往上看,底层是什么,那么A就是什么。*/

对于计算迭代器间的距离,重载两个函数,一个是一步一步不能跳的,一个是可以跳的

// distance 的 input_iterator_tag 的版本
template 
typename iterator_traits::difference_type
distance_dispatch(InputIterator first, InputIterator last, input_iterator_tag)
{ 																						//Input
  typename iterator_traits::difference_type n = 0;
  while (first != last)
  {
    ++first;
    ++n;
  }
  return n;
}
// distance 的 random_access_iterator_tag 的版本
template 
typename iterator_traits::difference_type
distance_dispatch(RandomIter first, RandomIter last, //Random
                  random_access_iterator_tag)
{
  return last - first;
}
//根据迭代器的类型选择哪个函数,根据函数的参数判断。

//advance差不多,多了个BidirectionalIterator,它可以后退,输入负数是可以的。

2020/7/1 未完结

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