virtual
コンテナ参照を返す関数がいくつかあるクラス階層があるとします。
#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;
};
現時点では、クラスの任意のサブクラスで実際にvector
、set
、またはを返すことしかできません。ただし、一部については、たとえば aを使用して、この制限を緩和できます。map
Interface
vector
gsl::array_view
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;
};
問題は、array_view
他のコンテナ タイプで使用するための代替手段があるかどうかです。基本的に私が欲しいのは、特定のコンテナー タイプを指定せずに、不変ビューとして機能する関数から返すことができる軽量オブジェクトだけです。std::set
a を のようなものに押し込むことも理にかなっていますarray_view
が、サポートされている操作は少なくなります (たとえば、ランダムアクセスはありません)。map
は明らかに別の獣であり、別のview
サポートする連想ルックアップが必要map
になりますが、array_view<const std::pair<const int, int>>
. 求めすぎですか?それとも、これを実装するための合理的な方法がありますか? それとも、そのような「ビュー」の既存の実装さえあるのでしょうか?
PS: 継承は前提条件ではありません。問題を提示する最も簡単な方法だと思いました。