Типичный пример циклов for (), основанных на диапазоне C ++ 11, всегда выглядит примерно так:
std::vector<int> numbers = { 1, 2, 3, 4, 5, 6, 7 };
for ( auto xyz : numbers )
{
std::cout << xyz << std::endl;
}
В каком случае xyz
это int
. Но что происходит, когда у нас есть что-то вроде карты? Какой тип переменной в этом примере:
std::map< foo, bar > testing = { /*...blah...*/ };
for ( auto abc : testing )
{
std::cout << abc << std::endl; // ? should this give a foo? a bar?
std::cout << abc->first << std::endl; // ? or is abc an iterator?
}
Когда просматриваемый контейнер является чем-то простым, похоже, что циклы for (), основанные на диапазоне, дадут нам каждый элемент, а не итератор. Что хорошо ... если бы это был итератор, первое, что мы всегда должны были бы сделать, это разыменовать его в любом случае.
Но я не понимаю, чего ожидать, когда речь идет о таких вещах, как карты и мультикарты.
(Я все еще на g ++ 4.4, хотя циклы на основе диапазона находятся в g ++ 4.6+, поэтому у меня еще не было возможности попробовать это).
c++
c++11
for-loop
dictionary
Stéphane
источник
источник
std::begin
иstd::end
функциями или функциями-членами под тем же именем.Ответы:
Каждый элемент контейнера является a
map<K, V>::value_type
, который являетсяtypedef
дляstd::pair<const K, V>
. Следовательно, в C ++ 17 или выше, вы можете написатьили как
если вы не планируете изменять значения.
В C ++ 11 и C ++ 14 вы можете использовать расширенные
for
циклы для извлечения каждой пары самостоятельно, а затем вручную извлекать ключи и значения:Вы могли бы также рассмотреть маркировку
kv
переменной,const
если вы хотите просматривать значения только для чтения.источник
В C ++ 17 это называется структурированными привязками , что позволяет:
источник
const &
ключ, но неконстантную ссылку на значение? (потому что это то, что делает map :: value_type ...)k
есть ,const
если вы используетеfor(auto&[k,v]:testing)
Из этой статьи: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n2049.pdf
for( type-specifier-seq simple-declarator : expression ) statement
синтаксически эквивалентно
Таким образом, вы можете ясно видеть, что
abc
в вашем случае будетstd::pair<key_type, value_type >
. Таким образом, для печати вы можете получить доступ к каждому элементуabc.first
иabc.second
источник
Если вы хотите видеть только ключи / значения на вашей карте и вам нравится использовать boost, вы можете использовать адаптеры boost с петлями на основе диапазона:
есть эквивалентный boost :: adapters :: key_values
http://www.boost.org/doc/libs/1_51_0/libs/range/doc/html/range/reference/adaptors/reference/map_values.html
источник
Если оператор присваивания копии foo и bar дешевый (например, int, char, указатель и т. Д.), Вы можете сделать следующее:
источник