Разрешено ли предикатам STL использовать адрес своего аргумента?

При написании пользовательской функции/функтора предиката для передачи алгоритму STL разрешено ли предикату использовать адрес своего аргумента?

Вот проблема, которая вдохновила вопрос. У меня есть вектор vec и вектор inds, который содержит некоторые индексы в vec. Я хотел бы удалить те элементы в vec, чьи индексы перечислены в inds.

Один из подходов заключается в использовании remove_if с функтором-предикатом InInds, который определяет индекс своего аргумента в vec, взяв его адрес:

class InInds {
  private:

  const vector<Element>& vec_;
  const vector<int>& inds_;

  public:

  InInds(const vector<Element>& vec, const vector<int>& inds) 
    : vec_(vec), inds_(inds) {}

  bool operator()(const Element& element) {
    // WARNING: uses the ADDRESS of element, not its value. May not be kosher?
    int index = &element - &vec[0];
    return std::find(inds_.begin(), inds_.end(), index) != inds_.end();
  }

}

InInds работает, если вызывается непосредственно для элемента в vec. Он сломается, если будет вызван для копии элемента, поскольку адрес копии не будет полезен для определения индекса element.

Мой вопрос: будет ли этот предикат работать в remove_if для любого стандартного компилятора? Или предикаты строго предназначены для работы только со значениями, а не с адресами?


person SuperElectric    schedule 06.04.2012    source источник
comment
Просто используйте петлю. Попытки подогнать алгоритмы туда, где они не подходят, ничему не помогут.   -  person Nicol Bolas    schedule 07.04.2012
comment
@NicolBolas Должен ли я сделать вывод из вашего ответа, что использование адресов в предикатах определенно не соответствует стандартам?   -  person SuperElectric    schedule 07.04.2012
comment
Так это или нет, не имеет значения; проще и понятнее для всех участников просто написать цикл.   -  person Nicol Bolas    schedule 07.04.2012
comment
Я бы сказал, что яснее ли это, не имеет отношения к заданному вопросу ;) Это был, как вы заметите, вопрос о стандартах, а не о стиле.   -  person SuperElectric    schedule 26.04.2012


Ответы (1)


Использование remove_if с вашим предикатом неверно, так как remove_if обычно перемещает неудаленные элементы к началу диапазона. Вам нужно скопировать неудаленные элементы в другой контейнер, а не удалять их на месте.

person Eugene    schedule 06.04.2012