迭代向量中属性具有特定值的元素范围
iterators to range of elements in a vector whose attributes have specific value
我有一个对象向量,我想返回属性具有特定值的元素范围。这是结构:
class A {
public:
std::vector<B*> vec_;
pair<vector<B*>::iterator, vector<B*>::iterator> getElements(unsigned int attr_val);
unsigned int name() { return name_; }
private:
unsigned int name_;
};
class B {
public:
unsigned int attr() { return attr_; }
A* source() { return source_; }
B* dest() { return dest_; }
private:
A* source_;
B* dest_;
unsigned int attr_;
};
向量vec_
已按attr_
和dest_->name()
排序(按该顺序)。现在我想返回所有元素,其attr_
等于 attr_val
.
合适的stl算法(或者甚至有一个向量成员函数?)来实现getElements(unsigned int attr_val)
?
你需要
一个值传递给equal_range
,而显而易见的东西是指针。获得一个显而易见的方法就是创建一个具有正确值attr_
的B
实例,并编写一个仅涉及attr()
值的比较器。我假设您已经知道如何做到这一点,因为您设法对向量进行了排序;-)
如果向量中没有空指针,您可以改为这样做:
struct FindAttr {
unsigned int attr;
FindAttr(unsigned int attr) : attr(attr) {}
bool operator()(B *left, B *right) {
unsigned int leftval = left ? left->attr() : attr;
unsigned int rightval = right ? right->attr() : attr;
return leftval < rightval;
}
};
...
return equal_range(vec_.begin(), vec_.end(), nullptr, FindAttr(value));
你可以把它做成一个lambda:
return equal_range(vec_.begin(), vec_.end(), nullptr, [=value](B *left, B *right) {
unsigned int leftval = left ? left->attr() : attr;
unsigned int rightval = right ? right->attr() : attr;
return leftval < rightval;
});
您实际上可以完全删除指针,以给出我认为是"最干净"的解决方案:
struct FindAttr {
bool operator()(B *left, unsigned int rightval) {
return left->attr() < rightval;
}
bool operator()(unsigned int leftval, B *right) {
return leftval < right->attr();
}
};
...
return equal_range(vec_.begin(), vec_.end(), value, FindAttr());
AFAIK 与 lambda 没有直接等价物,因为 lambda 只能有一个调用签名。我想你可以写一个接受boost::variant
的lambda(或任何从unsigned int
和B*
隐式转换的类型,并记住它是哪一个)。
您正在寻找std::equal_range
,它基本上可以满足您的需求。界面为:
pair<It, It> equal_range(It first,
It last,
const T& value,
Compare comp);
comp
默认为 std::less
,而 又调用运算符 <
。
在您的情况下,实现可以是:
bool comparer(B* el, unsigned int value)
{
return el->attr() < value;
}
pair<vector<B*>::iterator, vector<B*>::iterator> A::getElements(unsigned int attr_val)
{
return equal_range(vec_.begin(), vec_end(), attr_val, comparer);
}
相关文章:
- 使用std::transform将一个范围的元素添加到另一个范围中
- 基于范围的 for 循环:迭代使用一个元素扩展的向量
- C++基于范围的 for 循环和元素副本
- 如果变量数据包含大于 vector 所有元素的整数,则仅在视觉工作室上接收"矢量下标超出范围"?
- 如何读/写或遍历 std::array 中的特定元素范围?
- 基于相邻元素 c++ 的分段误差范围的循环
- 是否存在一个范围::视图::group_by对应项,它将所有元素都考虑在内,而不是只考虑连续的元素
- 对于多个查询,查找在 l 到 r 范围内具有相同元素的最长公共子数组
- 我应该如何使用remove_if删除两个数字范围内的元素
- 从给定范围内的向量中查找最大元素
- 忽略元素的基于范围的 for 循环
- 包含每个 k 个列表中至少 1 个元素的最小元素范围的时间复杂度
- 矢量擦除范围内的元素
- 使用std :: lower_bound()打印元素范围以下某些值以下
- 迭代向量中属性具有特定值的元素范围
- 编辑2d数组中的元素范围
- 将元素范围从字符数组提取到字符串中
- 在C++中以相同的方式同时对两个元素范围进行分区
- 如何使用存储在列表中的特定元素范围初始化向量
- 对元素范围从0到9999的数组进行排序