Использование С++ std::equal в контейнере shared_ptr

У меня есть контейнер std::shared_ptr. Я хочу сравнить два контейнера, используя std::equal. В классе A определен оператор ==. Я хочу, чтобы equal сравнивал, эквивалентен ли каждый элемент, используя свой оператор ==, а не тот, который определен в shared_ptr.

Нужно ли мне сделать так, чтобы функция или объект функции передавались равными? Или есть что-то встроенное, что было бы проще (например, что-то определенное в ‹functional›)?


person Matt    schedule 31.03.2011    source источник


Ответы (3)


Вам понадобится функция, объект функции или лямбда-выражение (поскольку вы можете использовать std::shared_ptr, у вас уже включена некоторая часть C++0x).

В <functional> нет ничего, что могло бы вам помочь, но что-то есть в boost: косвенный итератор

#include <iostream>
#include <vector>
#include <algorithm>
#include <memory>
#include <boost/iterator/indirect_iterator.hpp>
int main()
{
        std::vector<std::shared_ptr<int>> v1;
        std::vector<std::shared_ptr<int>> v2;
        v1.emplace_back( new int(1) );
        v2.emplace_back( new int(1) );

        bool result =
            std::equal( boost::make_indirect_iterator(v1.begin()),
                        boost::make_indirect_iterator(v1.end()),
                        boost::make_indirect_iterator(v2.begin()));
        std::cout << std::boolalpha << result << '\n';
}
person Cubbi    schedule 31.03.2011
comment
Спасибо, но я избегал добавления зависимости от повышения. Жаль, что именно этого я и хочу... - person Matt; 31.03.2011
comment
@Matt: вы всегда можете написать свой собственный итератор разыменования, заголовок stackoverflow.com/questions/352152/ - person Cubbi; 31.03.2011
comment
Круто, я думаю, что я все еще буду использовать объект функции, потому что в этом случае это просто, но это интересная идея, если после этого мне понадобится больше подобных функций. - person Matt; 31.03.2011

Вы можете сделать что-то вроде следующего, предполагая, что у вас есть компилятор, поддерживающий лямбда-выражения, и что ни один элемент никогда не равен нулю:

bool CompareA(const vector<shared_ptr<A>>& first, 
              const vector<shared_ptr<A>>& second) {

   return equal(first.begin(), first.end(), second.begin(),
              [](const shared_ptr<A>& item1, const shared_ptr<A>& item2) -> bool{
                   return (*item1 == *item2);
               });
}
person bsruth    schedule 31.03.2011
comment
Возможно, лучше передавать shared_ptr по константной ссылке, так как их копирование немного дорого. - person Cubbi; 31.03.2011
comment
@Cubbi Правда, это также излишне увеличило счетчик ссылок. Изменил код. - person bsruth; 01.04.2011

Я лично думаю, что функциональный объект был бы лучшим выбором... все, что я видел в <functional>, зависит от наличия правильного типа сравнения, и это означало бы, что если вы не хотите сравнивать сами указатели, что вы каким-то образом потребуется разыменование этих указателей на объекты, на которые они указывают ... Я не вижу никаких помощников в STL, которые автоматически делают это разыменование для вас.

Спасибо,

Джейсон

person Jason    schedule 31.03.2011
comment
Да, это то, что я хотел, я тоже не думал, что это существует, но, возможно, я что-то упустил. - person Matt; 31.03.2011