我有一个对象向量,我想返回其属性具有特定值的元素范围。这是结构:
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
的所有元素。
实施getElements(unsigned int attr_val)
的适当的stl算法(或者甚至是矢量成员函数?)是什么?
答案 0 :(得分:2)
你需要一个值传递给equal_range
,显而易见的是指针。获得一个的显而易见的方法是创建一个B
的实例,其值为attr_
,并编写一个只涉及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没有直接等价,因为lambdas只能有一个调用签名。我想你可以编写一个带有boost::variant
的lambda(或任何从unsigned int
和B*
隐式转换的类型,并记住它是哪一个。)
答案 1 :(得分:0)
您正在寻找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);
}