Learning boost 2 Array

类别:编程语言 点击:0 评论:0 推荐:

Learning boost 2

Array

简介

boost::array是一个对c++数组的包装类。和stl::vector不同的是array和c++数组一样是一个静态大小的容器。请看下面的一个例子:

#include<boost/array.hpp>

 #include<iostream>

 using namespace std;

 int main()

 {

     boost::array<int,5> a={1,2,3,4,5};

     for (int i=0;i<5;++i)

          cout<<a[i]<<endl;

     return 0;

 }

 

构造

array的原形是:

template<typename T, std::size_t N> class array;

T表示元素的类型,N表示容器的大小。在这里,容器的大小N是模板的一个参数,这意味着不同容器大小的array类型是不同的。

 

array并没有提供线式的构造函数,只提供了一个对等号运算符的重载。

template<typename U> array& operator=(const array<U, N>&);

构造函数,拷贝构造函数都是用默认的。可以使用如下方法来构造array

boost::array<int,5> a={1,2,3,4,5};

boost::array<int,5> b=a;//使用默认的拷贝构造函数

boost::array<int,5> c;//默认的构造函数,其中每个元素的值是未知的

boost::array<int,5> d={1,2,3};//最后两个元素的值未知

boost::array<int,5> e={1,2,3,4,5,6};//编译错误

boost::array<int,6> f=a;//编译错误,因为array<int,6>和array<int,5>类型不同

boost::array<double,5> g=a;//正确

访问

和vector一样,array既支持迭代器也支持operator[]和at();

operator[]不提供越界保护,而at成员对于越界访问会抛出一个异常。

array支持的迭代器有:

l         iterator

l         const_iterator

l         reverse_iterator

l         const_reverse_iterator

相关的成员函数:

l         begin()

l         end()

l         rbegin()

l         rend()

l         front()

l         back()

由于这些东西和stl中使用的方法一样,就不多说了。

另外array提供了data()和c_array()成员函数,data返回const T*,c_array返回T*,都返回c++形式的数组,但是注意data是const的成员函数,c_array不是。

 

由于array非常简单,下面附上array的源代码:

/* The following code declares class array,

 * an STL container (as wrapper) for arrays of constant size.

 *

 * See

 *      http://www.josuttis.com/cppcode

 * for details and the latest version.

 * See

 *      http://www.boost.org/libs/array for Documentation.

 * for documentation.

 *

 * (C) Copyright Nicolai M. Josuttis 2001.

 * Distributed under the Boost Software License, Version 1.0. (See

 * accompanying file LICENSE_1_0.txt or copy at

 * http://www.boost.org/LICENSE_1_0.txt)

 *

 * 29 Jan 2004 - c_array() added, BOOST_NO_PRIVATE_IN_AGGREGATE removed (Nico Josuttis)

 * 23 Aug 2002 - fix for Non-MSVC compilers combined with MSVC libraries.

 * 05 Aug 2001 - minor update (Nico Josuttis)

 * 20 Jan 2001 - STLport fix (Beman Dawes)

 * 29 Sep 2000 - Initial Revision (Nico Josuttis)

 *

 * Jan 29, 2004

 */

#ifndef BOOST_ARRAY_HPP

#define BOOST_ARRAY_HPP

 

#include <cstddef>

#include <stdexcept>

#include <boost/assert.hpp>

 

// Handles broken standard libraries better than <iterator>

#include <boost/detail/iterator.hpp>

#include <algorithm>

 

// FIXES for broken compilers

#include <boost/config.hpp>

 

 

namespace boost {

 

    template<class T, std::size_t N>

    class array {

      public:

        T elems[N];    // fixed-size array of elements of type T

 

      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;

   

        // iterator support

        iterator begin() { return elems; }

        const_iterator begin() const { return elems; }

        iterator end() { return elems+N; }

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

 

        // reverse iterator support

#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) && !defined(BOOST_MSVC_STD_ITERATOR) && !defined(BOOST_NO_STD_ITERATOR_TRAITS)

        typedef std::reverse_iterator<iterator> reverse_iterator;

        typedef std::reverse_iterator<const_iterator> const_reverse_iterator;

#elif defined(_MSC_VER) && (_MSC_VER == 1300) && defined(BOOST_DINKUMWARE_STDLIB) && (BOOST_DINKUMWARE_STDLIB == 310)

        // workaround for broken reverse_iterator in VC7

        typedef std::reverse_iterator<std::_Ptrit<value_type, difference_type, iterator,

                                      reference, iterator, reference> > reverse_iterator;

        typedef std::reverse_iterator<std::_Ptrit<value_type, difference_type, const_iterator,

                                      const_reference, iterator, reference> > const_reverse_iterator;

#else

        // workaround for broken reverse_iterator implementations

        typedef std::reverse_iterator<iterator,T> reverse_iterator;

        typedef std::reverse_iterator<const_iterator,T> const_reverse_iterator;

#endif

 

        reverse_iterator rbegin() { return reverse_iterator(end()); }

        const_reverse_iterator rbegin() const {

            return const_reverse_iterator(end());

        }

        reverse_iterator rend() { return reverse_iterator(begin()); }

        const_reverse_iterator rend() const {

            return const_reverse_iterator(begin());

        }

 

        // 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];

        }

 

        // 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]; }

   

        // 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];

        }

 

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

 

        // swap (note: linear complexity)

        void swap (array<T,N>& y) {

            std::swap_ranges(begin(),end(),y.begin());

        }

 

        // direct access to data (read-only)

        const T* data() const { return elems; }

 

        // use array as C array (direct read/write access to data)

        T* c_array() { return elems; }

 

        // assignment with type conversion

        template <typename T2>

        array<T,N>& operator= (const array<T2,N>& rhs) {

            std::copy(rhs.begin(),rhs.end(), begin());

            return *this;

        }

 

        // assign one value to all elements

        void assign (const T& value)

        {

            std::fill_n(begin(),size(),value);

        }

 

        // check range (may be private because it is static)

        static void rangecheck (size_type i) {

            if (i >= size()) {

                throw std::range_error("array<>: index out of range");

            }

        }

 

    };

 

    // comparisons

    template<class T, std::size_t N>

    bool operator== (const array<T,N>& x, const array<T,N>& y) {

        return std::equal(x.begin(), x.end(), y.begin());

    }

    template<class T, std::size_t N>

    bool operator< (const array<T,N>& x, const array<T,N>& y) {

        return std::lexicographical_compare(x.begin(),x.end(),y.begin(),y.end());

    }

    template<class T, std::size_t N>

    bool operator!= (const array<T,N>& x, const array<T,N>& y) {

        return !(x==y);

    }

    template<class T, std::size_t N>

    bool operator> (const array<T,N>& x, const array<T,N>& y) {

        return y<x;

    }

    template<class T, std::size_t N>

    bool operator<= (const array<T,N>& x, const array<T,N>& y) {

        return !(y<x);

    }

    template<class T, std::size_t N>

    bool operator>= (const array<T,N>& x, const array<T,N>& y) {

        return !(x<y);

    }

 

    // global swap()

    template<class T, std::size_t N>

    inline void swap (array<T,N>& x, array<T,N>& y) {

        x.swap(y);

    }

 

} /* namespace boost */

 

#endif /*BOOST_ARRAY_HPP*/

 

本文地址:http://com.8s8s.com/it/it23719.htm