c++ - Can raw pointers be used instead of iterators with STL algorithms for containers with linear storage? -


i have custom vector container internally stores item linear array. last night, trying implement custom iterators class able use them stl algorithms. have had success can see in here:

live example custom iterators

while doing so, discovered can merely pass raw pointers stl algorithm , seem work fine. here's example without iterators:

#include <cstddef> #include <iostream> #include <iterator> #include <algorithm>  template<typename t> class my_array{     t* data_;     std::size_t size_;  public:      my_array()         : data_(null), size_(0)     {}     my_array(std::size_t size)         : data_(new t[size]), size_(size)     {}     my_array(const my_array<t>& other){         size_ = other.size_;         data_ = new t[size_];         (std::size_t = 0; i<size_; i++)             data_[i] = other.data_[i];     }     my_array(const t* first, const t* last){         size_ = last - first;         data_ = new t[size_];          (std::size_t = 0; i<size_; i++)             data_[i] = first[i];     }      ~my_array(){         delete [] data_;     }     const my_array<t>& operator=(const my_array<t>& other){         size_ = other.size_;         data_ = new t[size_];         (std::size_t = 0; i<size_; i++)             data_[i] = other.data_[i];         return other;     }     const t& operator[](std::size_t idx) const {return data_[idx];}     t& operator[](std::size_t& idx) {return data_[idx];}     std::size_t size(){return size_;}      t* begin(){return data_;}     t* end(){return data_+size_;} };  template<typename t> void print(t t) {     std::cout << t << std::endl; }  int main(){       typedef float scalar_t;     scalar_t list [] = {1, 3, 5, 2, 4, 3, 5, 10, 10};     my_array<scalar_t> a(list, list+sizeof(list)/sizeof(scalar_t));      // works!     (scalar_t* = a.begin(), *end = a.end();          != end; ++it)         std::cout << ' ' << *it;     std::cout << std::endl;      // works!     std::for_each(a.begin(), a.end(), print<scalar_t>);     std::cout << std::endl;      // works!     my_array<int> b(a.size());     std::copy(a.begin(), a.end(), b.begin());      // works!     scalar_t* end = std::remove(a.begin(), a.end(), 5);     std::for_each(a.begin(), end, print<scalar_t>);     std::cout << std::endl;      // works!     std::random_shuffle(a.begin(), end);     std::for_each(a.begin(), end, print<scalar_t>);     std::cout << std::endl;      // works!     std::cout << "counts of 3 in array = " << std::count(a.begin(), end, 3) << std::endl << std::endl;      // works!     std::sort(a.begin(), end);     std::for_each(a.begin(), end, print<scalar_t>);     std::cout << std::endl;      // works!     if (!std::binary_search(a.begin(), a.end(), 5))         std::cout << "removed!" << std::endl;      return 0; } 

live example without iterators

my questions here following:

  1. does work containers have linear storage? know not work linked-lists example.
  2. if work in situation, why should ever go through hassle of implementing iterators anyway? know how iterators generalize code , whatnot, if simple array is ever need don't see point.
  3. what negative issues of i'm doing if approach work? 1 thing, can see i'm breaking data encapsulation.

one of features of iterators being based on operator-overloading, pointers random-access iterators. big design win in days of stl, made easier use algorithms existing code (as making interface more familiar programmers). it's reasonable wrap array, add typedef t* iterator; typedef const t* const_iterator, return &array[0] begin() , &array[size] end(), , use container iterator-based algorithm. realise, work container elements contiguous in memory (such array).

you might implement 'real' iterators if:

  • you have different-shaped container (such tree or list);
  • you want able resize array without invalidating iterators;
  • you want add debugging checks iterator use, example check if iterator used after being invalidated or after container has been deleted, or bounds-check;
  • you want introduce type-safety, , make sure people can't accidentally assign arbitrary t* my_array::iterator.

i'd last advantage alone worth writing trivial wrapper class for. if don't take advantage of c++'s type system making different kinds of thing have different types, might switch javascript :-)


Comments

Popular posts from this blog

java - Jmockit String final length method mocking Issue -

asp.net - Razor Page Hosted on IIS 6 Fails Every Morning -

c++ - wxwidget compiling on windows command prompt -