Supponiamo ho qualche gerarchia di classe che ha un paio di virtual
funzioni che restituisce un riferimento contenitore:array_view alternativa per le mappe, set, ecc
#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;
};
Al momento, è possibile solo per tornare in realtà un vector
, set
o map
in qualsiasi sottoclasse della classe Interface
. Tuttavia, per la parte vector
, ho potuto utilizzare, per esempio, un gsl::array_view
per ammorbidire questa restrizione:
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;
};
Quindi la domanda è: esiste un'alternativa per un array_view
per l'uso con altri tipi di contenitori? Fondamentalmente tutto ciò che vorrei avere è un oggetto leggero che potrei restituire da una funzione che agisce come una vista immutabile per alcuni contenitori senza specificare un tipo specifico di contenitore. Sarebbe anche sensato da parte mia spingere un std::set
a qualcosa come un array_view
, ma con meno operazioni supportate (ad es., Nessun accesso casuale). map
è chiaramente una bestia diversa e richiederebbe un diverso view
che supporta la ricerca associativa, ma anche per un map
penso che sarebbe utile avere la possibilità di dire array_view<const std::pair<const int, int>>
. Sto chiedendo troppo? O forse ci sono modi ragionevoli per implementarlo? O forse ci sono anche implementazioni esistenti di tali "punti di vista"?
PS: l'ereditarietà non è un prerequisito: ho solo pensato che fosse il modo più semplice per presentare il problema.
'any_range' è un tipo di visualizzazione, giusto? (una specie di implicita nella parola "range") ho dato un'occhiata ai suoi documenti, e questa affermazione non è rimasta impressa nelle poche pagine che ho letto. – Yakk
@Yakk Non sei sicuro del significato specifico del termine "tipo di visualizzazione", ma sono abbastanza sicuro che non puoi inserire/rimuovere elementi. Puoi modificare gli elementi tramite 'any_range' tho. – Barry
Mi chiedevo se ne fa una copia, in pratica. Probabilmente no. – Yakk