1

我有一个对象向量,我想返回其属性具有特定值的元素范围。这是结构:

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_and排序dest_->name()(按该顺序)。现在我想返回所有attr_等于attr_val.

什么是合适的 stl 算法(或者甚至有向量成员函数?)来实现getElements(unsigned int attr_val)

4

2 回答 2

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 直接等效的方法,因为 lambda 只能有一个调用签名。我想你可以编写一个接受 a 的 lambda boost::variant(或任何从两者unsigned int和 from隐式转换的类型B*,并且记住它是哪一个)。

于 2012-12-13T11:26:24.120 回答
0

您正在寻找std::equal_range,它基本上可以满足您的需求。界面是:

pair<It, It> equal_range(It first,
                         It last,
                         const T& value,
                         Compare comp);

comp默认为std::less,依次调用 operator <

在您的情况下,实现可能是:

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);
}
于 2012-12-13T11:14:29.573 回答