Let's assume I have some class hierarchy that has a couple of virtual
functions returning a container reference:
#include <vector>
#include <set>
#include <map>
#include <unordered_set>
#include <unordered_map>
class Interface {
public:
virtual const std::vector<int>& getArray() const = 0;
virtual const std::set<int>& getSet() const = 0;
virtual const std::map<int, int>& getMap() const = 0;
};
class SubclassA : public Interface {
public:
const std::vector<int>& getArray() const override { return _vector; }
const std::set<int>& getSet() const override { return _set; }
const std::map<int, int>& getMap() const override { return _map; }
private:
std::vector<int> _vector;
std::set<int> _set;
std::map<int, int> _map;
};
At the moment, it is only possible to actually return a vector
, set
, or map
in any subclass of the Interface
class. However, for the vector
part, I could use, e.g., a gsl::array_view
to soften this restriction:
class Interface {
public:
virtual gsl::array_view<const int> getArray() const = 0;
virtual const std::set<int>& getSet() const = 0;
virtual const std::map<int, int>& getMap() const = 0;
};
class SubclassA : public Interface {
public:
gsl::array_view<const int> getArray() const override { return _vector; }
const std::set<int>& getSet() const override { return _set; }
const std::map<int, int>& getMap() const override { return _map; }
private:
std::vector<int> _vector;
std::set<int> _set;
std::map<int, int> _map;
};
class SubclassB : public Interface {
public:
gsl::array_view<const int> getArray() const override { return _array; }
// const std::set<int>& getSet() const override { return _set; }
// const std::map<int, int>& getMap() const { return _map; }
private:
std::array<int, 3> _array;
std::unordered_set<int> _set;
std::unordered_map<int, int> _map;
};
So the question is, is there an alternative for an array_view
for use with other container types? Basically all I would like to have is a lightweight object that I could return from a function that would act as an immutable view to some container without specifying a specific container type. It would even make sense to me to shove a std::set
to something like an array_view
, but with fewer supported operations (e.g., no random access). map
is clearly a different beast and would require a different view
supporting associative lookup, but even for a map
I think it would be useful to have the ability to say array_view<const std::pair<const int, int>>
. Am I asking for too much? Or perhaps there are reasonable ways to implement this? Or maybe there are even existing implementations of such 'views'?
PS: inheritance is not a prerequisite - I just thought that it's the easiest way to present the problem.
any_range
is a view type, right? (sort of implied by the wordrange
) I glanced at its docs, and that claim didn't stick out in the few pages I read. – Ladysmith