Should I return gsl :: span <const T> instead of const std :: vector <T> &
I have a class with std :: vector <int> member and a member function that returns a constant reference to this vector.
class demo { public: //... const std::vector<int> & test() const { return iv; } private: std::vector<int> iv; };
I plan to change the element type to another array, such as a container type, with sufficient functionality and smaller memory size (for example, std :: experimental :: dynarray, std :: unique_ptr <int []>). Therefore, I thought it would be nice not to return the real container as a reference to const, but to return the view to the elements in the form gsl :: span <const int>.
class demo { public: //... gsl::span<const int> test() const { return iv; } private: std::vector<int> iv; };
But this breaks the code that worked with the constant vector <int> & because two instances of the same unmodified vector cannot be used to iterate over the elements:
demo d; std::cout << (d.test().begin() == d.test().begin()) << "\n"; std::cout << (d.test().end() == d.test().end()) << "\n"; for( auto it = d.test().begin(), end = d.test().end(); it != end; ++it ) std::cout << *it << "\n";
This prints 0 0 and then crashes because the test it! = End never fails. Of course, a cycle-based range, but this cycle is valid and therefore should also work properly. I expected that all gaps from the same range of the same container are equal, so the iterators of any of these gaps are comparable (the container does not change, of course). Of course, there is a good reason why this is not so.
So my question is: what is the best way to return such a representation to array elements, such as a container whose type should not be visible to the caller.