2009-06-27 31 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())添加到普通数组中。