#c #boost #stl #map #subtraction
#c #повысить #stl #словарь #вычитание
Вопрос:
Итак, у меня есть 2 std::map
s <string, shared_ptr<file> >
, один «старый», другой «новый», я хочу получить, какие файлы были удалены, и, таким образом, иметь возможность выполнять итерации по-разному и делать некоторые вещи с shared_ptr. Возможно ли такое и как это сделать?
Комментарии:
1. Взгляните на
std::set_difference
.
Ответ №1:
Хотя достаточно легко написать это самостоятельно (повторить 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 amp; a, const my_map::value_type amp; b)
{ return a.first < b.first; }
);
}
Если вы хотите написать это самостоятельно, вам следует подумать о том, чтобы воспользоваться тем фактом, что оба диапазона уже отсортированы, так что вы можете добиться большего, чем плоский поиск существования, продвигая два итератора параллельно.
Если у вас нет C 11, просто используйте этот предикат вместо лямбда:
bool my_comp(const my_map::value_type amp; a, const my_map::value_type amp; b)
{
return a.first < b.first;
}
Остерегайтесь, что нет сравнения по отображенному типу! Таким образом, если у вас один и тот же строковый ключ на обеих картах, то в результате такого элемента не будет, даже если два сопоставленных значения отличаются. Если это нежелательно, вам нужен другой выходной контейнер (например, a std::multimap<my_map::key_type, my_map::mapped_type>
) и другой предикат.