Я нахожу повышение:: 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::map
s. Документация только имеет примеры с типами такой как vector
или string
.
Вам необходимо использовать:
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. карта
, которая неверна. Это упомянуто в каждой документации.
Да:
typedef std::map<std::string,int> MyMap;
MyMap myMap;
BOOST_FOREACH(MyMap::value_type loop, myMap)
{
// Stuff
}
Это возможно, но это не очень лучший способ Делать вещи (как я упоминал несколько раз ранее, 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"));
Я использую Ассортимент 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";
Конечно, вы можете. Трюк, однако, что шапка итератор указывает на пару ключ и ценности. Это будет выглядеть что-то подобное:
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;
}