Я хочу добавить две карты вместе со следующим поведением.Добавление двух карт вместе
Если ключ существует -> добавьте два ключевых значения вместе.
Если ключ не существует -> Вставьте пару в карту.
Я рассмотрел несколько стандартных алгоритмов библиотеки. А именно преобразование, но, похоже, не делает того, что я хочу.
Взятые из этого LINK
template < class InputIterator, class OutputIterator, class UnaryOperator >
OutputIterator transform (InputIterator first1, InputIterator last1,
OutputIterator result, UnaryOperator op)
{
while (first1 != last1)
*result++ = op(*first1++); // or: *result++=binary_op(*first1++,*first2++);
return result;
}
Мои мысли из этого, где я бы только один итератор из моей второй карты при использовании и соответствующий функтор
*result++=binary_op(*first1++,*first2++);
Поэтому я не буду в состоянии чтобы перебрать вторую карту, чтобы найти значение ключа.
Одна мысль заключалась только в том, чтобы сделать мой собственный алгоритм с тонким изменением.
template < class InputIterator, class ContainerType, class BinaryOperator >
void myTransform (InputIterator first1, InputIterator last1,
ContainerType cont2,
BinaryOperator binary_op)
{
while (first1 != last1)
binary_op(first1++, cont2); //cont2 passed by reference
}
Я бы тогда быть в состоянии использовать:
cont2.find()
в моем функторе искать всю карту.
Здесь был бы более полный пример того, что я думал, но я, кажется, получаю компиляционную ошибку, которую я не могу решить (я вроде догадываюсь, что тип BinaryOperator ... см. Ниже)?
#include <map>
#include <string>
#include <iostream>
template < class InputIterator, class ContainerType, class BinaryOperator >
void myTransform (InputIterator first1, InputIterator last1,
ContainerType &cont2,
BinaryOperator binary_op)
{
while (first1 != last1)
binary_op(first1++, cont2); //cont2 passed by reference
}
template<class IteratorType, class ContainerType>
struct AddMapValues:
std::binary_function<IteratorType, ContainerType, void>
{
void operator()(IteratorType itr, ContainerType& cont)
{
if(cont.find(itr->first) != cont.end()) cont[itr->first] = cont.find(itr->first).second + itr->second;
else cont.insert((*itr));
}
};
int main()
{
typedef std::map<std::string, double> stringDoubleMap;
typedef std::map<std::string, double>::iterator stringDoubleMapItr;
typedef void (*ptrfnt)(stringDoubleMapItr, stringDoubleMap&);
stringDoubleMap map1;
stringDoubleMap map2;
map1.insert(stringDoubleMap::value_type("Test1",1.0));
map1.insert(stringDoubleMap::value_type("Test2",2.0));
map1.insert(stringDoubleMap::value_type("Test3",3.0));
map2.insert(stringDoubleMap::value_type("Test1",1.0));
map2.insert(stringDoubleMap::value_type("Test2",2.0));
map2.insert(stringDoubleMap::value_type("Test3",3.0));
myTransform(map1.begin(), map1.end(),
map2,
AddMapValues< stringDoubleMapItr, stringDoubleMap >());
return 0;
}
Вот моя ошибка компилятора:
testingMapTransforms.cxx: In function ‘int main()’:
testingMapTransforms.cxx:52:85: error: no matching function for call to ‘myTransform(std::map<std::basic_string<char>, double>::iterator, std::map<std::basic_string<char>, double>::iterator, stringDoubleMap&, std::map<std::basic_string<char>, double>::iterator, AddMapValues<std::_Rb_tree_iterator<std::pair<const std::basic_string<char>, double> >, std::map<std::basic_string<char>, double> >)’
testingMapTransforms.cxx:52:85: note: candidate is:
testingMapTransforms.cxx:12:20: note: template<class InputIterator, class ContainerType, class OutputIterator, class BinaryOperator> OutputIterator myTransform(InputIterator, InputIterator, ContainerType, OutputIterator, BinaryOperator)
Там, кажется, еще один итератора приходит откуда-то и тип контейнера не правильно читать?
Любые идеи?
Я использую
GCC - Проект GNU C и компилятор C++
с
Ubuntu/Linaro 4.6.3-1ubuntu5
Благодарности
ПРИМЕЧАНИЕ:
Я обновил рабочую версию кода выше в ответ. Если вы думаете, что я должен просто изменить код вопроса, то дайте мне знать. Не уверен в лучшей практике
Есть ли причина, по которой вы не можете просто сделать это вручную? –
Я думаю, что вы делаете много операций в одной строке; '* result ++ = op (* first1 ++);' такой код трудно отлаживать, и он не очень читабельен. – Spo1ler
@ Spo1ler полностью согласен. пусть компилятор выполнит свою работу по оптимизации и вместо этого код, чтобы другие люди могли его прочитать. –