西城

指尖代码,手上年华

联系 聚合 管理
  20 Posts :: 0 Stories :: 62 Comments :: 0 Trackbacks
首先,命名空间为boost,array较小,只有一个单独的array.hpp文件。
array的目的主要是在STL的动态数组与传统功能有限的普通数组之间做一个折衷。为高效的静态数组增添一些其他的功能。

 

template<class T,std::size_t N>
class array{
public:
T elems[N];

 

内部的底层实现即用的传统的数组。数组的大小由初始化时指定,但类型则由模板指定。

public:
// type definitions
typedef T value_type;
typedef T* iterator;
typedef const T* const_iterator;
typedef T& reference;
typedef const T& const_reference;
typedef std::size_t size_type;
typedef std::ptrdiff_t difference_type;

类似于STL的特性萃取机制。

// iterator support
iterator begin() { return elems; }
const_iterator begin() const { return elems; }
const_iterator cbegin() const { return elems; }

iterator end() { return elems+N; }
const_iterator end() const { return elems+N; }
const_iterator cend() const { return elems+N; }


提供类似于STL容器的接口。但这里的实现很简单,因为是静态数组。注意end()返回的指针是指向
数组之后的一位,这点同STL的接口一致。

reverse_iterator rbegin() { return reverse_iterator(end()); }
const_reverse_iterator rbegin() const {
return const_reverse_iterator(end());
}
const_reverse_iterator crbegin() const {
return const_reverse_iterator(end());
}

reverse_iterator rend() { return reverse_iterator(begin()); }
const_reverse_iterator rend() const {
return const_reverse_iterator(begin());
}
const_reverse_iterator crend() const {
return const_reverse_iterator(begin());
}

反向迭代器,也是类似于STL中的功能,在具体实现上就是用的STL的函数将普通迭代器转化。

// operator[]
reference operator[](size_type i)
{
BOOST_ASSERT( i < N && "out of range" );
return elems[i];
}

const_reference operator[](size_type i) const
{
BOOST_ASSERT( i < N && "out of range" );
return elems[i];
}

重载【】操作符,两个版本:const和非const.BOOST_ASSERT是BOOST库提供的静态断言功能,可以在编译期
发现错误。比如说在程序编译时就可以发现数组越界,报错。C的最新标准里也加入了静态断言的内容。

// at() with range check
reference at(size_type i) { rangecheck(i); return elems[i]; }
const_reference at(size_type i) const { rangecheck(i); return elems[i]; }

at()访问函数。亦分const 与非const 版本,二者的不同体现杂返回值上。注意前面的定义,reference
为T&,const_reference为const T&.实现上首先也是边界检查,我们来看一下rangecheck函数

// check range (may be private because it is static)
static void rangecheck (size_type i) {
if (i >= size()) {
std::out_of_range e("array<>: index out of range");
boost::throw_exception(e);
}
}

若游标大于界限,则抛出异常,std::out_of_range,

class out_of_range : public logic_error {
public:
explicit out_of_range (const string& what_arg);
};


class logic_error : public exception {
public:
explicit logic_error (const string& what_arg);
};

这里的异常的主要是为了向编译者提供一个清晰的错误说明。

// front() and back()
reference front()
{
return elems[0];
}

const_reference front() const
{
return elems[0];
}

reference back()
{
return elems[N-1];
}

const_reference back() const
{
return elems[N-1];
}

front和back函数,实现起来是很简单的,也很高效的。

// size is constant
static size_type size() { return N; }
static bool empty() { return false; }
static size_type max_size() { return N; }
enum { static_size = N };

类似于STL容器的返回大小的接口。因为是静态数组,大小不变,所以主要的目的只是为了与STL
的接口兼容,实现起来并没有多大意义。像empty()函数,对vector来说很有用,但对一个长度固定的
函数则是没有什么意义的(总是返回false),所以在设计上主要的考虑是在别的地方。

// swap (note: linear complexity)
void swap (array<T,N>& y) {
for (size_type i = 0; i < N; ++i)
boost::swap(elems[i],y.elems[i]);
}

boost:swap是utility中的一个组件。其实现如下:

namespace boost
{
template<class T1, class T2>
void swap(T1& left, T2& right)
{
::boost_swap_impl::swap_impl(left, right);
}
}

而swap_impl的实现在boost命名空间之外。

namespace boost_swap_impl
{
template<class T>
void swap_impl(T& left, T& right)
{
using namespace std;//use std::swap if argument dependent lookup fails
swap(left,right);
}

template<class T, std::size_t N>
void swap_impl(T (& left)[N], T (& right)[N])
{
for (std::size_t i = 0; i < N; ++i)
{
::boost_swap_impl::swap_impl(left[i], right[i]);
}
}
}

boost:swap有两个template的好处是可以很好地与std:swap分别开来。当同时出现时,std:swap是优先的。

// direct access to data (read-only)
const T* data() const { return elems; }
T* data() { return elems; }

直接返回数组首地址。

T* c_array() { return elems; }

直接返回数组首地址用于进行C类型的数组操作。

template <typename T2>
array<T,N>& operator= (const array<T2,N>& rhs) {
std::copy(rhs.begin(),rhs.end(), begin());
return *this;
}

赋值操作符。用的是STL中的通用算法。

void assign (const T& value) { fill ( value ); } // A synonym for fill
void fill (const T& value)
{
std::fill_n(begin(),size(),value);
}

posted on 2012-03-24 23:05 西城 阅读(1475) 评论(1)  编辑 收藏 引用 所属分类: Boost

Feedback

# re: Boost:array源码解析 2012-03-25 09:49 tb
很棒的   回复  更多评论
  


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理