Это один из возможных способов выхода:
struct RetrieveKey
{
template <typename T>
typename T::first_type operator()(T keyValuePair) const
{
return keyValuePair.first;
}
};
map<int, int> m;
vector<int> keys;
// Retrieve all keys
transform(m.begin(), m.end(), back_inserter(keys), RetrieveKey());
// Dump all keys
copy(keys.begin(), keys.end(), ostream_iterator<int>(cout, "\n"));
Конечно, мы также можем извлечь все значения из карты, определив другой функтор RetrieveValues .
Есть ли другой способ достичь этого легко? (Мне всегда интересно, почему std :: map не включает функцию-член для нас.)
c++
dictionary
stl
stdmap
Оуэн
источник
источник
keys.reserve(m.size());
.Ответы:
Хотя ваше решение должно работать, его может быть сложно прочитать в зависимости от уровня навыков ваших коллег-программистов. Кроме того, он перемещает функциональность от сайта вызова. Что может сделать обслуживание немного сложнее.
Я не уверен, что ваша цель - вставить ключи в вектор или напечатать их для cout, поэтому я делаю и то, и другое. Вы можете попробовать что-то вроде этого:
Или даже проще, если вы используете Boost:
Лично мне нравится версия BOOST_FOREACH, потому что она меньше печатает и очень четко рассказывает о том, что она делает.
источник
BOOST_FOREACH
? Код, который вы предлагаете здесь, абсолютно неверенv.reserve(m.size())
чтобы избежать изменения размера вектора во время передачи.источник
it = ...begin(); it != ...end
. Самым хорошим будет, конечно, std :: map с методом keys (), возвращающим этот вектор ...answered Mar 13 '12 at 22:33
, то есть через несколько месяцев после того, как C ++ 11 стал C ++.for(auto const & imap : mapints)
.Для этого есть адаптер диапазона усиления :
Есть аналогичный адаптер диапазона map_values для извлечения значений.
источник
boost::adaptors
не доступен до Boost 1.43. Текущий стабильный выпуск Debian (Squeeze) предлагает только Boost 1.42boost/range/adaptor/map.hpp
C ++ 0x дал нам еще одно отличное решение:
источник
@ DanDan ответ, используя C ++ 11:
и используя C ++ 14 (как отмечено @ ivan.ukr), мы можем заменить
decltype(map_in)::value_type
наauto
.источник
keys.reserve(map_in.size());
для эффективности.SGI STL имеет расширение под названием
select1st
. Жаль, что это не в стандартной STL!источник
Ваше решение хорошо, но вы можете использовать итератор для этого:
источник
Основано на решении @ rusty-parks, но в c ++ 17:
источник
std::ignore
можно использовать структурированные привязки. Я получаю ошибку компиляции. Достаточно просто использовать обычную переменную, например,ignored
которая просто не используется.std::ignore
предназначен для использования,std::tie
но не со структурными привязками. Я обновил свой кодЯ думаю, что BOOST_FOREACH, представленный выше, хорош и чист, однако есть и другой вариант, использующий BOOST.
Лично я не думаю, что этот подход такой же чистый, как подход BOOST_FOREACH в этом случае, но boost :: lambda может быть действительно чистым в других случаях.
источник
Также, если у вас есть Boost, используйте transform_iterator, чтобы избежать создания временной копии ключей.
источник
Бит с ++ 11 взять:
источник
Вы можете использовать универсальный boost :: transform_iterator. Transform_iterator позволяет вам преобразовывать повторяющиеся значения, например, в нашем случае, когда вы хотите иметь дело только с ключами, а не со значениями. См. Http://www.boost.org/doc/libs/1_36_0/libs/iterator/doc/transform_iterator.html#example
источник
Вот хороший шаблон функции с использованием магии C ++ 11, работающей как для std :: map, так и для std :: unordered_map:
Проверьте это здесь: http://ideone.com/lYBzpL
источник
Лучшее не-sgi, не поддерживающее STL решение - это расширить map :: iterator следующим образом:
а затем использовать их так:
источник
На примере атомарной карты
источник
Немного похоже на один из примеров, упрощенный с
std::map
точки зрения использования.Используйте как это:
источник
map.size()
означает двойной возврат размера вектора. Пожалуйста , исправьте , чтобы спасти кого - то еще головная боль :(Потому что он не может сделать это лучше, чем ты можешь. Если реализация метода не превосходит реализацию свободной функции, то в общем случае вы не должны писать метод; Вы должны написать бесплатную функцию.
Также не сразу понятно, почему это так или иначе полезно.
источник
empty()
причине мы не должны иметь, потому что это может быть реализовано какsize() == 0
.std::map<T,U>
как контейнер пар. В Python adict
действует как его ключи при повторении, но позволяет вамd.items()
получить поведение C ++. Python также предоставляетd.values()
.std::map<T,U>
безусловно , может обеспечитьkeys()
иvalues()
метод , который возвращает объект , который имеетbegin()
иend()
которые обеспечивают итераторы над ключами и значениями.