美文网首页
C++11 标准库源代码剖析:连载之三

C++11 标准库源代码剖析:连载之三

作者: JackZou | 来源:发表于2018-05-12 15:05 被阅读0次

std::array

std::arrayc-style数组的对象化包装。我们知道c-style数组在使用时很痛苦的一点是数组本身并不知道自己有多少个元素,所以我们不得不花很大的精力确保数组不会越界。而std::array克服了这一缺陷,它自带size信息,这使得它使用起来很方便,我们来看几个例子:

#include <string>
#include <iterator>
#include <iostream>
#include <algorithm>
#include <array> 
 
int main(){
    // construction uses aggregate initialization
    std::array<int, 3> a1{ {1, 2, 3} }; // double-braces required in C++11 (not in C++14)
    std::array<int, 3> a2 = {1, 2, 3};  // never required after =
    std::array<std::string, 2> a3 = { std::string("a"), "b" };
 
    // container operations are supported
    std::sort(a1.begin(), a1.end());
    std::reverse_copy(a2.begin(), a2.end(), std::ostream_iterator<int>(std::cout, " "));
 
    std::cout << '\n';
 
    // ranged for loop is supported
    for(const auto& s: a3)
        std::cout << s << ' ';
}

输出:

3 2 1
a b

std::array源代码分析

相较于很多类——比如tuplebind等——那如天书一般的源代码,std::array的源代码算是真正的良心之作,几乎不需要什么智商就能看明白:

template<class _Tp, size_t _Size>
struct array {
   // types:
   typedef array __self;
   typedef _Tp                                   value_type;
   typedef value_type&                           reference;
   typedef const value_type&                     const_reference;
   typedef value_type*                           iterator;
   typedef const value_type*                     const_iterator;
   typedef value_type*                           pointer;
   typedef const value_type*                     const_pointer;
   typedef size_t                                size_type;
   typedef ptrdiff_t                             difference_type;
   typedef std::reverse_iterator<iterator>       reverse_iterator;
   typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
   
   // 唯一的成员,c-style数组
   value_type __elems_[_Size > 0 ? _Size : 1];
   
   // ...

看到了吧,刨去那一大堆的typedefstd::array就只有一个成员:__elems_,这是一个c-style的数组std::array就是就是C原生数组的一个马甲而已。

当然,这个马甲有个很好的特性:自带size信息:

template<class _Tp, size_t _Size>
struct array {
   // ...
   // capacity:
   inline constexpr size_type size() const noexcept {return _Size;}
   inline constexpr bool empty() const noexcept {return _Size == 0;}
   // ...
};

另外,这个穿上马甲的std::array已经摇身一变成了一个容器,既然是容器,就必须遵循C++标准可以关于容器的concept,比如遍历,获取元素等等:

template<class _Tp, size_t _Size>
struct array {
   // ...
   // iterators:
   inline constexpr iterator begin() noexcept {return iterator(__elems_);}
   inline constexpr iterator end() noexcept {return iterator(__elems_ + _Size);}
   // ...
   
   // element access:
   inline constexpr reference operator[](size_type __n) {return __elems_[__n];}
   constexpr reference at(size_type __n) {
      if (__n >= _Size) __throw_out_of_range("array:at");
      return __elems_[__n];
   }
   // ...
};

源代码确实很简单,就不多讲了。最后再说点题外话:swap,我们来看看std::array是怎样实现swap的:

template <class _Tp, size_t _Size>
struct array{
   // ...
   
   inline void swap(array& __a) noexcept(_Size == 0 || __is_nothrow_swappable<_Tp>::value) {
      __swap_dispatch((std::integral_constant<bool, _Size == 0>()), __a);
   }
   
   inline void __swap_dispatch(std::true_type, array&){}
   
   inline void __swap_dispatch(std::false_type, array& __a) {
      std::swap_range(__elems_, __elems_ + _Size, __a.__elems_);
   }
};

template<class _Tp, size_t _Size>
inline
typename enable_if<_Size == 0 || __is_swappable<_Tp>::value, void>::type
swap(array<_Tp, _Size>& __x, array<_Tp, _Size>& __y) {
   __x.swap(__y);
}

相关文章

网友评论

      本文标题:C++11 标准库源代码剖析:连载之三

      本文链接:https://www.haomeiwen.com/subject/rjfhdftx.html