Как вычесть один список ключей карты из другого и получить новую карту (карта A - mab B = карта C) - PullRequest
5 голосов
/ 10 октября 2011

Итак, у меня есть 2 std::map s <string, shared_ptr<file> > один - «старый», один - «новый». Я хочу получить файлы, которые были удалены, и поэтому иметь возможность выполнять итерации по разным и делать некоторые вещи с shared_ptr.Возможна ли такая вещь и как это сделать?

1 Ответ

9 голосов
/ 10 октября 2011

Хотя достаточно легко написать это самостоятельно (перебрать A и проверить, присутствует ли ключ в B), это похоже на работу для std::set_difference.Нам понадобится лямбда или некоторый пользовательский предикат для сравнения ключей, хотя:

#include <iterator>
#include <map>
#include <string>
#include <algorithm>

typedef std::map<std::string, MyPtr> my_map;

my_map A; // given
my_map B; // given

void make_a_difference()
{
  my_map C; // will hold the result

  std::set_difference(A.begin(), A.end(),
                      B.begin(), B.end(),
                      std::insert_iterator<my_map>(C, C.end()),
              [](const my_map::value_type & a, const my_map::value_type & b)
              { return a.first < b.first; }
                     );
}

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

Если у вас нет C ++ 11, просто используйте этот предикат вместо лямбды:

bool my_comp(const my_map::value_type & a, const my_map::value_type & b)
{
  return a.first < b.first;
}

Остерегайтесь , что нет сопоставления для сопоставленного типа!Поэтому, если у вас одинаковый строковый ключ на обеих картах, в результате такого элемента не будет, даже если два сопоставленных значения различаются.Если это нежелательно, вам нужен другой выходной контейнер (например, std::multimap<my_map::key_type, my_map::mapped_type>) и другой предикат.

...