Позволено ли е на 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