大家都希望可以像操作STL容器一樣的去運算元組,C++可沒有提供這個東西,有時候你會選擇使用vector來替代,不過這畢竟不是個好的辦法,畢竟vector類比動態數組比較穩妥,而用它去替代一個普通的數組,開銷畢竟太大了。而恰好,boost::array就為你提供了這個功能。
1. 這樣的集合體有如下特點:
(1)無使用者聲明的建構函式。
(2)無私人的或保護的非待用資料成員。
(3)無基類。
(4)無虛擬函數。
boost::array的定義如下(簡化):
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; } // operator[] reference operator[](size_type i) ; const_reference operator[](size_type i) const ; // at() with range check reference at(size_type i) ; const_reference at(size_type i) const ; // front() and back() reference front() ; const_reference front() const ; reference back() ; const_reference back() const ; // 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) ; }
2. at與[ ]區別
這兩者都是通過下標訪問元素, 但是在越界檢查上不一樣:
at: 可以用try..catch方法, 擷取拋出的異常.
[]: 會拋出assert錯誤,但總比沒有強
具體例子可以看看:
void test_array(){ // 1. boost::array的構造方法 const int ELEMS = 6; 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; int ar[] = {9, 8, 7, 1, 2, 3, 6, 4, 5}; // 2. boost::array可以擷取數組的長度. // 而std::array卻沒有這個功能, 要用sizeof(array)/sizeof(value_type)來代替 boost::array<int, ELEMS>::size_type num = values2.size(); // 6 boost::array<int, ELEMS>::size_type maxnum = values2.max_size(); // 6 int arsize = sizeof(ar)/sizeof(int); // 9 // 3. 越界異常 try { values1.at(10) = 10; } catch (std::exception& e) { std::cout << e.what() << std::endl; } // 拋出assert錯誤 // values1[10]; // 4. begin, cbegin, end, cend, front, end等容器的函數均可用 std::copy(values1.cbegin(), values1.cend(), std::ostream_iterator<int>(std::cout, " ")); std::cout << std::endl; int i1 = values1.front(); int i2 = values1.back(); assert(i1 == 3); assert(i2 == 8); // 5. 整體操作資料很方便 values4.assign(66);}
3. 普通數組, boost::array, boost::vector效能比較
const int _SIZE = 20000;template<typename T>void test_array_task(T _int){// std::cout << _int << std::endl;for (int i = 0; i < _SIZE; ++i){for (int j = 0; j < _SIZE; ++j){_int[j] = j;}}}void test_array_performance(){// 1. 普通數組{int _int[_SIZE];boost::progress_timer pt;test_array_task<int[]>(_int);}// 2. boost::array{boost::array<int, _SIZE> a_int;boost::progress_timer pt;test_array_task<boost::array<int, _SIZE> >(a_int);}// 3. std::vector{std::vector<int> b_int;b_int.resize(_SIZE);boost::progress_timer pt;test_array_task<std::vector<int> >(b_int);}}
release運行結果:
0.40 s0.39 s0.42 s
debug運行結果:
1.54 s17.75 s33.42 s
發現release的結果: boost::array的運行效能甚至比普通數組要好.