给定std::vector<T>
,我如何创建一个公开std::vector<std::pair<T, T>>
接口的视图,其中每对由底层向量中的两个连续元素组成?
目标是在同一存储上创建多个容器抽象,即std::vector<T>
。 T
类型是某种受歧视的联盟,{la Boost Variant。给出了存储要求,否则我只会使用std::vector<std::pair<T, T>>
。我想要支持的存储视图是集合(唯一元素)和表格(关联数组,唯一键)。虽然前者通过确保设置唯一性属性是直截了当的,但后者需要处理键和值。
为了支持std::vector<T>
上的关联数组语义,我目前认为最好的方法是创建一个std::vector<std::pair<T, T>>
形式的视图,并且这个视图允许我使用STL算法来保持所需的属性。这听起来像是一个好策略吗?还有其他想法吗?
如果我有一个遍历每个偶数元素的迭代器 i 和遍历每个奇数元素的迭代器 j ,那么我会想到Boost的zip iterator,将启用(i,j)对中的迭代。但我的用例略有不同,因为我没有两个独立的容器。
答案 0 :(得分:2)
似乎Boost的iterator_facade
确实是我想要的。这是一个玩具示例(边缘粗糙):
#include <algorithm>
#include <iostream>
#include <vector>
#include <boost/iterator/iterator_facade.hpp>
template <typename Value>
class pair_iterator
: public boost::iterator_facade<
pair_iterator<Value>
, Value
, boost::random_access_traversal_tag
, std::pair<Value&, Value&>
, typename std::vector<Value>::difference_type
>
{
public:
typedef std::vector<Value> vector_type;
typedef typename vector_type::difference_type difference_type;
typedef typename vector_type::iterator iterator;
pair_iterator()
: i_(0)
{
}
explicit pair_iterator(iterator i)
: i_(i)
{
}
private:
friend class boost::iterator_core_access;
bool equal(pair_iterator<Value> const& other) const
{
return i_ == other.i_;
}
void increment()
{
++i_;
++i_;
}
std::pair<Value&, Value&> dereference() const
{
return { std::ref(*i_), std::ref(*(i_ + 1)) };
}
void advance(difference_type n)
{
i_ += n << 1;
}
difference_type distance_to(pair_iterator<Value> const& other) const
{
return other.i_ - i_;
}
iterator i_;
};
int main()
{
typedef pair_iterator<int> int_map_iterator;
std::vector<int> v{2, 20, 3, 30, 5, 50, 7, 70};
int_map_iterator first(v.begin());
int_map_iterator last(v.end());
std::for_each(first + 1, last,
[](std::pair<int&, int&> p)
{
std::cout
<< p.first << " -> "
<< p.second << std::endl;
});
return 0;
}
输出结果为:
3 -> 30
5 -> 50
7 -> 70
iterator
到const_iterator
的转换问题。dereference()
实现时才有效。答案 1 :(得分:0)
首先要注意的是,您将无法公开std::pair<T const, T>&
作为修改对象的方法。然而,可能足够接近的是std::pair<T const, T&>
因为你只能改变第二部分。
这样看起来你需要
std::pair<T const, T&>
。