Ошибка компилятора на самом деле довольно лаконична:
error: cannot convert 'std::pair<const std::basic_string<char>, int>' to 'int' in assignment
И это именно то, в чем проблема.map
, с которого вы копируете, имеет итераторы, которые обращаются к pair<KEY,VALUE>
, и нет способа неявно преобразовать a pair<KEY,VALUE>
в VALUE
.
, потому чтоиз этого вы не можете использовать copy
или copy_if
для копирования из map
в vector
;но Стандартная библиотека предоставляет алгоритм, который вы можете использовать, творчески названный transform
.transform
очень похож на copy
в том, что он требует двух исходных итераторов и целевого итератора.Разница в transform
также принимает унарную функцию, которая выполняет фактическое преобразование.Используя лямбду C ++ 11, вы можете скопировать все содержимое map
в vector
следующим образом:
transform( m.begin(), m.end(), back_inserter(v), [] (const MyMap::value_type& vt)
{
return vt.second;
});
Что если вы не хотите копировать все содержимоеmap
, но только некоторые элементы, отвечающие определенным критериям?Просто, просто используйте transform_if
.
Что это, вы говорите?В стандартной библиотеке нет transform_if
?Ну, да, у вас есть точка там.К сожалению, в стандартной библиотеке нет transform_if
.Однако написание одного является достаточно простой задачей.Вот код:
template<class InputIterator, class OutputIterator, class UnaryFunction, class Predicate>
OutputIterator transform_if(InputIterator first,
InputIterator last,
OutputIterator result,
UnaryFunction f,
Predicate pred)
{
for (; first != last; ++first)
{
if( pred(*first) )
*result++ = f(*first);
}
return result;
}
Как и следовало ожидать, использование transform_if
похоже на взятие copy_if
и объединение его с transform
.Вот некоторый псевдокод для демонстрации:
transform_if( m.begin(), m.end(), back_inserter(v),
[] (const MyMap::value_type& vt) // The UnaryFunction takes a pair<K,V> and returns a V
{
return vt.second;
}, [] (const MyMap::value_type& vt) // The predicate returns true if this item should be copied
{
return 0 == (vt.second%2);
} );