title: Can raw pointers be used instead of iterators with STL algorithms for containers with linear storage?
body: <p>I have a custom vector container that internally stores item a linear array. Last night, I was trying to implement custom iterators for my class to be able to use them with STL algorithms. I have had some success that you can see in here:</p>
  
  <p><a href="http://ideone.com/7YdiQY" rel="noreferrer">Live example with custom iterators</a></p>
  
  <p>While doing so, I discovered I can merely pass raw pointers to STL algorithm and they just seem to work fine. Here's the example without any iterators:</p>
  
  <pre><code>#include &lt;cstddef&gt;
  #include &lt;iostream&gt;
  #include &lt;iterator&gt;
  #include &lt;algorithm&gt;
  
  template&lt;typename T&gt;
  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&lt;T&gt;&amp; other){
          size_ = other.size_;
          data_ = new T[size_];
          for (std::size_t i = 0; i&lt;size_; i++)
              data_[i] = other.data_[i];
      }
      my_array(const T* first, const T* last){
          size_ = last - first;
          data_ = new T[size_];
  
          for (std::size_t i = 0; i&lt;size_; i++)
              data_[i] = first[i];
      }
  
      ~my_array(){
          delete [] data_;
      }
      const my_array&lt;T&gt;&amp; operator=(const my_array&lt;T&gt;&amp; other){
          size_ = other.size_;
          data_ = new T[size_];
          for (std::size_t i = 0; i&lt;size_; i++)
              data_[i] = other.data_[i];
          return other;
      }
      const T&amp; operator[](std::size_t idx) const {return data_[idx];}
      T&amp; operator[](std::size_t&amp; idx) {return data_[idx];}
      std::size_t size(){return size_;}
  
      T* begin(){return data_;}
      T* end(){return data_+size_;}
  };
  
  template&lt;typename T&gt;
  void print(T t) {
      std::cout &lt;&lt; t &lt;&lt; std::endl;
  }
  
  int main(){
  
  
      typedef float scalar_t;
      scalar_t list [] = {1, 3, 5, 2, 4, 3, 5, 10, 10};
      my_array&lt;scalar_t&gt; a(list, list+sizeof(list)/sizeof(scalar_t));
  
      // works!
      for (scalar_t* it = a.begin(), *end = a.end();
           it != end; ++it)
          std::cout &lt;&lt; ' ' &lt;&lt; *it;
      std::cout &lt;&lt; std::endl;
  
      // works!
      std::for_each(a.begin(), a.end(), print&lt;scalar_t&gt;);
      std::cout &lt;&lt; std::endl;
  
      // works!
      my_array&lt;int&gt; 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&lt;scalar_t&gt;);
      std::cout &lt;&lt; std::endl;
  
      // works!
      std::random_shuffle(a.begin(), end);
      std::for_each(a.begin(), end, print&lt;scalar_t&gt;);
      std::cout &lt;&lt; std::endl;
  
      // works!
      std::cout &lt;&lt; "Counts of 3 in array = " &lt;&lt; std::count(a.begin(), end, 3) &lt;&lt; std::endl &lt;&lt; std::endl;
  
      // works!
      std::sort(a.begin(), end);
      std::for_each(a.begin(), end, print&lt;scalar_t&gt;);
      std::cout &lt;&lt; std::endl;
  
      // works!
      if (!std::binary_search(a.begin(), a.end(), 5))
          std::cout &lt;&lt; "Removed!" &lt;&lt; std::endl;
  
      return 0;
  }
  </code></pre>
  
  <p><a href="http://ideone.com/AEVnn0" rel="noreferrer">Live example without iterators</a></p>
  
  <p>My questions here are the following:</p>
  
  <ol>
  <li>Does this always work for containers that have linear storage? I know that this would not work for linked-lists for example.</li>
  <li>If they do work in this situation, why should I ever go through the hassle of implementing iterators anyway? I know how iterators generalize my code and whatnot, but if this simple array <em>is</em> all I ever need then I don't see the point.</li>
  <li>What are the negative issues of what I'm doing if this approach would always work? For one thing, I can see I'm breaking data encapsulation.</li>
  </ol>