Это возможный использовать повышение:: foreach со станд.:: карта?

Я нахожу повышение:: foreach, очень полезный, поскольку это сохраняет меня большая запись. Например, скажем, я хочу распечатать все элементы в списке:

std::list numbers = { 1, 2, 3, 4 };
for (std::list::iterator i = numbers.begin(); i != numbers.end(); ++i)
   cout << *i << " ";

повышение:: foreach делает код выше большого количества simplier:

std::list numbers = { 1, 2, 3, 4 };
BOOST_FOREACH (int i, numbers)
   cout << i << " ";

Намного лучше! Однако я никогда не выяснял путь (если это вообще возможно) использовать его для std::maps. Документация только имеет примеры с типами такой как vector или string.

52
задан Thomas Bonini 20 January 2010 в 09:17
поделиться

5 ответов

Вам необходимо использовать:

typedef std::map<int, int> map_type;
map_type map = /* ... */;

BOOST_FOREACH(const map_type::value_type& myPair, map)
{
    // ...
}

Причина в том, что макрос ожидает два параметра. Когда вы пытаетесь встроить определение пара, вы представляете вторую запятую, вместо этого заставляя макрос три параметра. Препроцессор не уважает какие-либо конструкции C ++, он только знает текст.

Так что, когда вы говорите Boost_Foreach (пара , карта) , препроцессор видит эти три аргумента для макроса:

1. Пара
2. int>
3. карта

, которая неверна. Это упомянуто в каждой документации.

88
ответ дан 7 November 2019 в 09:13
поделиться

Да:

typedef std::map<std::string,int>    MyMap;

MyMap    myMap;

BOOST_FOREACH(MyMap::value_type loop, myMap)
{ 
       // Stuff
}
1
ответ дан 7 November 2019 в 09:13
поделиться

Это возможно, но это не очень лучший способ Делать вещи (как я упоминал несколько раз ранее, for_each почти никогда не так, и boost_foreach только лучше лучше). Для вашего первого примера, я думаю, вам будет лучше с:

std::copy(numbers.begin(), numbers.end(), 
          std::ostream_iterator<int>(std::cout, " "));

Это работает довольно похоже на карту, за исключением того, что вы должны определить оператор << для этого, так как его уже не определено:

typedef map<std::string, int>::value_type vt;

std::ostream &operator<<(std::ostream &os, vt &v) { 
    return os << v.first << ": " << v.second;
}

... И еще раз, STD :: Copy делает работу довольно красиво:

std::copy(mymap.begin(), mymap.end(), 
          std::ostream_iterator<vt>(std::cout, "\n"));
2
ответ дан 7 November 2019 в 09:13
поделиться
121 --- 3926812-

Я использую Ассортимент Boost Ex Ex , которая реализует какой-то необычный диапазон адаптеры для итерации по поводу ключей или значений карты. Например:

map<int, string> foo;
foo[3] = "three";
foo[7] = "seven";

BOOST_FOREACH(i, foo | map_keys)
   cout << i << "\n";


BOOST_FOREACH(str, foo | map_values)
   cout << str << "\n";
20
ответ дан 7 November 2019 в 09:13
поделиться

Конечно, вы можете. Трюк, однако, что шапка итератор указывает на пару ключ и ценности. Это будет выглядеть что-то подобное:

typedef std::map<std::string, int> MapType;
MapType myMap;

// ... fill the map...

BOOST_FOREACH(MapType::value_type val, myMap)
{
    std::cout << val.first << ": " << val.second << std::endl;
}
3
ответ дан 7 November 2019 в 09:13
поделиться
Другие вопросы по тегам:

Похожие вопросы: