一 Boost::array
在以前,如果我们要处理一组数据,我们可能使用一般数组存储,或者需要许多的对数组的数据的操作的时候,我们使用STL容器存储。但是如果我们的需求是,我们能够提前固定一组数据的大小,或提前知道这组数据的大小,但是我们又想这组数据进行一些操作,比如排序。。。显然对这个情况,上面的使用原始数组或STL容器都有点不太合适,因为原始的数组显得笨重,的我们自己实现一些重复的功能,但是如果是使用STL容器的话,有可能会导致空间和性能的下降。
基于上面的情况,所以在Boost中引入Boost::array,也可能会被加入下一代的C++标准中。Boost::array,内部仍然是固定长度,但是却拥有向STL容器一样的接口,这样就使的Boost::array能够支持STL中的算法,省去了很多的重复的工作,提高开发效率。
二 源码剖析
template<class Ty, size_t N>
class array {
public:
typedef size_t size_type;
typedef ptrdiff_t difference_type;
typedef Ty& reference;
typedef const Ty& const_reference;
typedef Ty *pointer;
typedef const Ty *const_pointer;
typedef T0 iterator;
typedef T1 const_iterator;
typedef Ty value_type;
typedef reverse_iterator<iterator>reverse_iterator;
typedef reverse_iterator<const_iterator>
const_reverse_iterator;
void assign(const Ty& val);
void swap(array& right);
iterator begin();
const_iterator begin() const;
iterator end();
const_iterator end() const;
reverse_iterator rbegin();
const_reverse_iterator rbegin() const;
reverse_iterator rend();
const_reverse_iterator rend() const;
size_type size() const;
size_type max_size() const;
bool empty() const;
reference operator[](size_type off);
const_reference operator[](size_type off) const;
reference at(size_type off);
const_reference at(size_type off) const;
reference front();
const_reference front() const;
reference back();
const_reference back() const;
T *data();
const T *data() const;
};
template<class Ty, size_t N>
class array;
// FUNCTION TEMPLATES
template<class Ty, size_t N>
bool operator==(
const array<Ty, N>& left,
const array<Ty, N>& right);
template<class Ty, size_t N>
bool operator!=(
const array<Ty, N>& left,
const array<Ty, N>& right);
template<class Ty, size_t N>
bool operator<(
const array<Ty, N>& left,
const array<Ty, N>& right);
template<class Ty, size_t N>
bool operator<=(
const array<Ty, N>& left,
const array<Ty, N>& right);
template<class Ty, size_t N>
bool operator>(
const array<Ty, N>& left,
const array<Ty, N>& right);
template<class Ty, size_t N>
bool operator>=(
const array<Ty, N>& left,
const array<Ty, N>& right);
template<class Ty, size_t N>
void swap(
array<Ty, N>& left,
array<Ty, N>& right);
// tuple-LIKE INTERFACE
template<int Idx, class Ty, size_t N>
Ty& get(array<Ty, N>& arr);
template<int Idx, class Ty, size_t N>
const Ty& get(const array<Ty, N>& arr);
template<class Ty, size_t N>
class tuple_element<array<Ty, N> >;
template<class Ty, size_t N>
class tuple_size<array<Ty, N> >;
class array {
public:
typedef size_t size_type;
typedef ptrdiff_t difference_type;
typedef Ty& reference;
typedef const Ty& const_reference;
typedef Ty *pointer;
typedef const Ty *const_pointer;
typedef T0 iterator;
typedef T1 const_iterator;
typedef Ty value_type;
typedef reverse_iterator<iterator>reverse_iterator;
typedef reverse_iterator<const_iterator>
const_reverse_iterator;
void assign(const Ty& val);
void swap(array& right);
iterator begin();
const_iterator begin() const;
iterator end();
const_iterator end() const;
reverse_iterator rbegin();
const_reverse_iterator rbegin() const;
reverse_iterator rend();
const_reverse_iterator rend() const;
size_type size() const;
size_type max_size() const;
bool empty() const;
reference operator[](size_type off);
const_reference operator[](size_type off) const;
reference at(size_type off);
const_reference at(size_type off) const;
reference front();
const_reference front() const;
reference back();
const_reference back() const;
T *data();
const T *data() const;
};
template<class Ty, size_t N>
class array;
// FUNCTION TEMPLATES
template<class Ty, size_t N>
bool operator==(
const array<Ty, N>& left,
const array<Ty, N>& right);
template<class Ty, size_t N>
bool operator!=(
const array<Ty, N>& left,
const array<Ty, N>& right);
template<class Ty, size_t N>
bool operator<(
const array<Ty, N>& left,
const array<Ty, N>& right);
template<class Ty, size_t N>
bool operator<=(
const array<Ty, N>& left,
const array<Ty, N>& right);
template<class Ty, size_t N>
bool operator>(
const array<Ty, N>& left,
const array<Ty, N>& right);
template<class Ty, size_t N>
bool operator>=(
const array<Ty, N>& left,
const array<Ty, N>& right);
template<class Ty, size_t N>
void swap(
array<Ty, N>& left,
array<Ty, N>& right);
// tuple-LIKE INTERFACE
template<int Idx, class Ty, size_t N>
Ty& get(array<Ty, N>& arr);
template<int Idx, class Ty, size_t N>
const Ty& get(const array<Ty, N>& arr);
template<class Ty, size_t N>
class tuple_element<array<Ty, N> >;
template<class Ty, size_t N>
class tuple_size<array<Ty, N> >;
比较简单,只要用过STL容器的,都能明白,最后的几个get,tuple_element,是在tr1中才有的,为了和tuple接口兼容。
三 实例
#include <algorithm>
#include <iostream>
#include <stdexcept>
#include "boost/array.hpp"
const int ELEMS = 6;
template <class Container>
void do_sort (Container& values)
{
std::sort (values.begin(), values.end());
}
int main()
{
boost::array<int, ELEMS> values1 = { 3, 1, 4, 2, 9, 8 };
boost::array<int, ELEMS> values2 = {2,2,2};
boost::array<int, ELEMS> values3(values1);
boost::array<int, ELEMS> values4 = values2;
boost::array<int, ELEMS>::size_type num = values1.size();
boost::array<int, ELEMS>::size_type maxnum = values1.max_size();
bool isEmpty = values1.empty();
// test for get function
boost::array<int, 10> squares = { 0, 1, 4, 9, 16,25, 36, 49, 64, 81 };
int idx = -1;
for (;;)
{
try {
std::cout << idx << " squared is "
<< squares .at(idx) << '\n';
break;
}
catch(std::exception&)
{
std::cout << "Value to square: ";
std::cin >> idx;
}
}
int ninesquare = squares[9];
// test for iterator
boost::array<int, ELEMS> values = { 3, 1, 4, 2, 9, 8 };
std::copy(values.begin(), values.end(),
std::ostream_iterator<int>(std::cout, " "));
std::cout << '\n';
std::sort(values.rbegin(), values.rend());
std::copy(values.begin(), values.end(),
std::ostream_iterator<int>(std::cout, " "));
std::cout << '\n';
// test assign and swap
boost::array<int,5> myarr1 = {1,2,3,4,5};
boost::array<int,10> myarr2;
myarr2.assign(10);
boost::array<int,12> myarr3;
//myarr3.swap(myarr1); // error
boost::array<int,5> myarr;
myarr.swap(myarr1);
int* my1 = myarr1.c_array();
int* my2 = myarr1.data();
return 0;
}
#include <iostream>
#include <stdexcept>
#include "boost/array.hpp"
const int ELEMS = 6;
template <class Container>
void do_sort (Container& values)
{
std::sort (values.begin(), values.end());
}
int main()
{
boost::array<int, ELEMS> values1 = { 3, 1, 4, 2, 9, 8 };
boost::array<int, ELEMS> values2 = {2,2,2};
boost::array<int, ELEMS> values3(values1);
boost::array<int, ELEMS> values4 = values2;
boost::array<int, ELEMS>::size_type num = values1.size();
boost::array<int, ELEMS>::size_type maxnum = values1.max_size();
bool isEmpty = values1.empty();
// test for get function
boost::array<int, 10> squares = { 0, 1, 4, 9, 16,25, 36, 49, 64, 81 };
int idx = -1;
for (;;)
{
try {
std::cout << idx << " squared is "
<< squares .at(idx) << '\n';
break;
}
catch(std::exception&)
{
std::cout << "Value to square: ";
std::cin >> idx;
}
}
int ninesquare = squares[9];
// test for iterator
boost::array<int, ELEMS> values = { 3, 1, 4, 2, 9, 8 };
std::copy(values.begin(), values.end(),
std::ostream_iterator<int>(std::cout, " "));
std::cout << '\n';
std::sort(values.rbegin(), values.rend());
std::copy(values.begin(), values.end(),
std::ostream_iterator<int>(std::cout, " "));
std::cout << '\n';
// test assign and swap
boost::array<int,5> myarr1 = {1,2,3,4,5};
boost::array<int,10> myarr2;
myarr2.assign(10);
boost::array<int,12> myarr3;
//myarr3.swap(myarr1); // error
boost::array<int,5> myarr;
myarr.swap(myarr1);
int* my1 = myarr1.c_array();
int* my2 = myarr1.data();
return 0;
}