template class vec { public: // default constructor vec(){ m_size = 0; m_capacity = 2; m_data = new T[m_capacity]; // std::cout << "calling default constructor" << std::endl; } // other constructor vec(int number, const T& value){ m_size = number; m_capacity = m_size * 2; m_data = new T[m_capacity]; for(int i=0; i(){ return ptr; } // pre-increment iterator& operator++(){ ++ptr; return *this; } // post-increment // special syntax here, we must write the int keyword here in the post-increment function. iterator operator++(int){ iterator temp = *this; ++ptr; return temp; } bool operator!=(const iterator& other){ return (ptr != other.ptr); } }; iterator begin(); //iterator begin(){ // we want to have an iterator pointing to the beginning of the vec container. // return iterator(m_data); //} iterator end(){ // we want to have an iterator pointing to the end. return iterator(m_data + m_size); } private: T* m_data; int m_capacity; // whole capacity int m_size; // current size }; // below we demonstrate that member functions can also be written outside of the templated class definition: // why we need typename here: The compiler does not automatically assume that vec::iterator is a type. // Instead, it first assumes that anything after :: is a member variable or function, not a type. // To explicitly tell the compiler that vec::iterator is a type, we must use the typename keyword: template typename vec::iterator vec::begin(){ return vec::iterator(m_data); } template int vec::size(){ return m_size; }