Nehmen wir an, ich eine Klassenhierarchie, die ein paar virtual
Funktionen Zurückgeben eines Behälters Referenz hat: eine vector
array_view Alternative für Karten, Sets, etc
#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;
};
Im Moment ist es nur möglich, tatsächlich zurückkehren set
oder map
in einer beliebigen Unterklasse der Klasse Interface
. Ich konnte jedoch für den vector
Teil verwenden, beispielsweise ein gsl::array_view
diese Einschränkung zu erweichen:
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;
};
Die Frage ist also, gibt es eine Alternative für ein array_view
für die Verwendung mit anderen Containertypen? Grundsätzlich möchte ich nur ein leichtgewichtiges Objekt haben, das ich von einer Funktion zurückgeben könnte, die als unveränderliche Ansicht für einen Container fungiert, ohne einen bestimmten Containertyp anzugeben. Es würde sogar Sinn machen, einen std::set
zu etwas wie einem array_view
zu schieben, aber mit weniger unterstützten Operationen (z. B. kein wahlfreier Zugriff). map
ist eindeutig ein anderes Biest und würde erfordern eine andere view
Unterstützung assoziativen Lookup, aber auch für eine map
Ich denke, es wäre nützlich, die Fähigkeit zu sagen, array_view<const std::pair<const int, int>>
. Frage ich zu viel? Oder vielleicht gibt es vernünftige Möglichkeiten, dies zu implementieren? Oder vielleicht gibt es sogar Implementierungen solcher "Ansichten"?
PS: Vererbung ist keine Voraussetzung - ich dachte nur, dass es der einfachste Weg ist, das Problem zu präsentieren.
'any_range' ist ein Ansichtstyp, richtig? (eine Art impliziert durch das Wort 'range') Ich warf einen Blick auf seine Dokumente, und diese Behauptung zeichnete sich auf den wenigen Seiten, die ich las, nicht ab. – Yakk
@Yakk Nicht sicher, was der spezifische Begriff "Ansichtstyp" bedeutet, aber ich bin ziemlich sicher, dass Sie Elemente nicht einfügen/entfernen können. Sie können die Elemente über 'any_range' tho modifizieren. – Barry
Ich frage mich, ob es im Grunde eine Kopie macht. Wahrscheinlich nicht. – Yakk