0

I want to create a class to store data also dynamically - inside a range based loop. But I face problem to overload end() method. The idea is something like:

template<typename T>
class ContainerClass
{
public:
    typename std::vector<T>::iterator begin()
    {
        return _v.begin();
    }

    typename std::vector<T>::iterator end()
    {
        return _v.end();
    }

    void add(T a)
    {
        _v.push_back(a);
    }

private:
    std::vector<T> _v;
};

int main()
{
    ContainerClass<int> c;      
    c.add(1);
    c.add(2); 

    for (auto e : c)
    {
        std::cout << e << std::endl;

        if(input())
           c.add(3);
    }    
    return 0;
}
JeJo
  • 30,635
  • 6
  • 49
  • 88
Assen
  • 1
  • 2
  • Can you please be more specific what is the question? – Luke 10X Aug 09 '21 at 17:36
  • Yep. It seems (I keep researching) I need to create some special iterator for this kind of purpose and return it in begin() and end() overloads. But I'm open for other ideas too. – Assen Aug 11 '21 at 09:18

1 Answers1

2

This problem appears because of range-based for loop implementation. Possible implementation from cppreference:


{
   auto && __range = range_expression ;
   for (auto __begin = begin_expr, __end = end_expr; __begin != __end; ++__begin) {
      range_declaration = *__begin;
      loop_statement
   }
}

End pointer declares only at the beginning. When you add new element to the array inside the loop it allocates more memory and it leads to undefined behavior. If you reserve() more memory before for (auto e : c) it will output:

1
2
  • I can not change anything inside or before loop. This is the idea! This class I will use in other code with standard loops. – Assen Aug 09 '21 at 11:56
  • 1
    @Assen Then don't use range-based loop.But you still need to allocate more memory for _v vector. You can do it inside constructor. –  Aug 09 '21 at 12:03
  • useless. Vector alone is good enough for what you write. – Assen Aug 11 '21 at 09:22