gpt4 book ai didi

c++ - map 、集合等的 array_view 替代方案

转载 作者:塔克拉玛干 更新时间:2023-11-03 01:43:45 25 4
gpt4 key购买 nike

假设我有一些类层次结构,其中有几个 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 , 或 mapInterface 的任何子类中类(class)。但是,对于 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 是否有替代方案?与其他容器类型一起使用?基本上我想要的只是一个轻量级对象,我可以从一个函数返回它,该函数将充当某个容器的不可变 View ,而无需指定特定的容器类型。推 std::set 对我来说甚至有意义到类似 array_view 的东西,但支持的操作较少(例如,无随机访问)。 map显然是不同的野兽,需要不同的 view支持关联查找,但即使是 map我认为能够说 array_view<const std::pair<const int, int>> 会很有用.我要求太多了吗?或者也许有合理的方法来实现这个?或者甚至可能存在此类“ View ”的现有实现?

PS:继承不是先决条件 - 我只是认为这是呈现问题的最简单方法。

最佳答案

如果您只是在寻找类型删除的范围,您可以查看 boost::any_range :

using IntRange = boost::any_range<
int,
boost::forward_traversal_tag,
int,
std::ptrdiff_t>;

int sum(IntRange const& range) {
return std::accumulate(range.begin(), range.end(), 0);
}

int main()
{
std::cout << sum(std::vector<int>{1, 2, 3}) << std::endl; // OK, 6
std::cout << sum(std::set<int>{4, 5, 6}) << std::endl; // OK, 15
}

即使您试图滥用它:

sum(std::map<int, int>{})

错误信息并不可怕:

/usr/local/include/boost/range/detail/any_iterator_wrapper.hpp:40:60: error: invalid static_cast from type 'std::pair<const int, int>' to type 'int&'
return static_cast<Reference>(const_cast<T&>(x));
^

您可以为您的用例创建一个别名:

template <typename T>
using FwdImmutableRangeT = boost::any_range<T,
boost::forward_traversal_tag,
const T&, std::ptrdiff_t>;

并返回那些:

class Interface {
public:
virtual FwdImmutableRange<int> getArray() const = 0;
virtual FwdImmutableRange<const int> getSet() const = 0;
virtual FwdImmutableRange<std::pair<const int, int>> getMap() const = 0;
};

关于c++ - map 、集合等的 array_view 替代方案,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33389891/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com