2009-06-27 48 views
0

我需要一個數組,其中大小在編譯時已知。我知道我可以使用std :: vectorboost :: array。但這並不教我如何在內部工作。除了使用初始值設定項之外,我也找不到如何將項目添加到boost :: array。我已經爲通用數組編寫了以下代碼。我的目的是熟悉的迭代器,模板特等等以下是代碼實現一個支持迭代器的通用固定大小數組

template<typename T> 
struct iterator_traits 
{ 
    typedef T   value_type; 
    typedef T&   reference_type; 
    typedef T*   iterator; 
    typedef const T* const_iterator; 
    typedef std::reverse_iterator<iterator> reverse_iterator; 
}; 

template<typename T> 
struct iterator_traits<T*> 
{ 
    typedef T*   value_type; 
    typedef T*&   reference_type; 
    typedef T**   iterator; 
    typedef const T  const_iterator; 
    typedef std::reverse_iterator<iterator> reverse_iterator; 
}; 

template<typename T, size_t size = 10> 
class Array 
{ 
    public: 

     typedef typename iterator_traits<T>::value_type  value_type; 
     typedef typename iterator_traits<T>::reference_type reference_type; 
     typedef typename iterator_traits<T>::iterator   iterator; 
     typedef typename iterator_traits<T>::const_iterator const_iterator; 
     typedef typename iterator_traits<T>::reverse_iterator reverse_iterator; 

     Array() : lastIndex(0) { 
     } 

     void add(value_type element) { 
      if(lastIndex >= size) 
       throw std::out_of_range("Array is full"); 
      array_[lastIndex++] = element; 
     } 

     reference_type at(unsigned int index){ 
      if(index < size) 
       return array_[index]; 
      else 
       throw std::out_of_range("Invalid index"); 
     } 

     size_t capacity(){ 
      return size; 
     } 

     iterator begin(){ 
      return array_; 
     } 

     iterator end(){ 
      return array_ + size; 
     } 

     const_iterator begin() const{ 
      return array_; 
     } 

     const_iterator end() const{ 
      return array_ + size; 
     } 

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

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

    private: 

     value_type array_[size]; 
     unsigned int lastIndex; 
}; 

上面的代碼工作得很好。以下是我的問題

1 - 如何創建我的陣列,如boost :: array呢?類似於

Array<int> ints = { 10, 12 }; 

2 - 代碼中是否有任何缺陷?

3 - 我不得不使用專門的特質指針類型。這是最佳做法嗎?

4 - 迭代器模式是否正確實現?

任何想法都會很棒!

+1

std :: iterator_traits(#include )已經專門用於指針,你不需要提供你自己的指針。 – 2009-06-27 21:44:21

+1

你是什麼意思,你不能添加任何東西來提高:數組? – GManNickG 2009-06-27 22:14:39

回答

2

1 - 如何創建我的數組像boost :: array呢?像

Array<int> ints = { 10, 12 }; 

東西在C++中,你只能(目前)使用封閉初始化列表一個括號,如果你的結構,聯合或C數組滿足在一個總的標準。要做到這一點,根據標準:

8.5.1.1聚合是一個數組或類(第9章)沒有用戶提供的構造函數(12.1),沒有私有或受保護的非靜態數據成員(第11章),沒有基類(第10章),也沒有虛函數(10.3)。

如果你想在當前的標準中使用它們,你將不得不讓你的課程具備這些功能。下一個標準(見here)包含一個允許其他類型這樣做的規定。

2 - 代碼中是否有任何缺陷?

這裏是一個:你不能把東西添加到增強列表的原因是它總是有相同數量的元素(它被分配的大小)。在你的數組中你可以添加元素,但是在構建過程中你仍然在構造下構建了10個元素。這可能會導致一些驚人的結果,如果用戶不期望被稱爲10次的默認構造函數。

2

boost :: array使用語言的一個特性:沒有構造函數的struct可以使用初始化列表。如果您提供自己的構造函數,則不能使用初始化列表。

另外,您正在使用iterator_traits錯誤。你的代碼應該像

// 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_traits是用於迭代器的特徵。此外,你可以使用一個指針作爲迭代器。 STL明確允許這樣做。

1

2 - 有沒有什麼隱患?

我會擺脫默認大小「大小= 10」。 10是數組的默認大小是什麼?相反,我發現有人不小心忽略了規模,並假設它比它大。

關於添加元素和C風格的初始化,我不相信它可能做到這一點。它在boost中起作用,因爲(我相信)該對象非常簡單,是一個數組。它不能動態地重新調整大小。該類只是將迭代器(以及其他糖,如:: at())添加到普通數組中。