Non mi piaceva l'idea di dover aggiungere typedef ogni volta che volevo utilizzare un foreach su una mappa. Quindi ecco la mia implementazione basata sul codice spinta foreach:
#ifndef MUNZEKONZA_FOREACH_IN_MAP
#include <boost/preprocessor/cat.hpp>
#define MUNZEKONZA_FOREACH_IN_MAP_ID(x) BOOST_PP_CAT(x, __LINE__)
namespace munzekonza {
namespace foreach_in_map_private {
inline bool set_false(bool& b) {
b = false;
return false;
}
}
}
#define MUNZEKONZA_FOREACH_IN_MAP(key, value, map) \
for(auto MUNZEKONZA_FOREACH_IN_MAP_ID(_foreach_in_map_it) = map.begin(); \
MUNZEKONZA_FOREACH_IN_MAP_ID(_foreach_in_map_it) != map.end();) \
for(bool MUNZEKONZA_FOREACH_IN_MAP_ID(_foreach_in_map_continue) = true; \
MUNZEKONZA_FOREACH_IN_MAP_ID(_foreach_in_map_continue) && \
MUNZEKONZA_FOREACH_IN_MAP_ID(_foreach_in_map_it) != map.end(); \
(MUNZEKONZA_FOREACH_IN_MAP_ID(_foreach_in_map_continue)) ? \
((void)++MUNZEKONZA_FOREACH_IN_MAP_ID(_foreach_in_map_it)) : \
(void)0) \
if(munzekonza::foreach_in_map_private::set_false( \
MUNZEKONZA_FOREACH_IN_MAP_ID(_foreach_in_map_continue))) {} else \
for(key = MUNZEKONZA_FOREACH_IN_MAP_ID(_foreach_in_map_it)->first; \
!MUNZEKONZA_FOREACH_IN_MAP_ID(_foreach_in_map_continue); \
MUNZEKONZA_FOREACH_IN_MAP_ID(_foreach_in_map_continue) = true) \
if(munzekonza::foreach_in_map_private::set_false( \
MUNZEKONZA_FOREACH_IN_MAP_ID(_foreach_in_map_continue))) {} else \
for(value = MUNZEKONZA_FOREACH_IN_MAP_ID(_foreach_in_map_it)->second; \
!MUNZEKONZA_FOREACH_IN_MAP_ID(_foreach_in_map_continue); \
MUNZEKONZA_FOREACH_IN_MAP_ID(_foreach_in_map_continue) = true)
Quindi è possibile utilizzare nel codice: #define foreach_in_map MUNZEKONZA_FOREACH_IN_MAP
std::map<int, std::string> mymap;
mymap[0] = "oi";
mymap[1] = "noi";
std::map<int, std::string> newmap;
foreach_in_map(int key, const std::string& value, mymap) {
newmap[key] = value;
}
ASSERT_EQ(newmap.size(), 2);
ASSERT_EQ(newmap.count(0), 1);
ASSERT_EQ(newmap.count(1), 1);
ASSERT_EQ(newmap.at(0), "oi");
ASSERT_EQ(newmap.at(1), "noi");
È inoltre possibile modificare i valori: #define foreach_in_map MUNZEKONZA_FOREACH_IN_MAP
std::map<int, std::string> mymap;
mymap[0] = "oi";
mymap[1] = "noi";
std::map<int, std::string> newmap;
foreach_in_map(int key, std::string& value, mymap) {
value = "voronoi" + boost::lexical_cast<std::string>(key);
}
ASSERT_EQ(mymap.size(), 2);
ASSERT_EQ(mymap.count(0), 1);
ASSERT_EQ(mymap.count(1), 1);
ASSERT_EQ(mymap.at(0), "voronoi0");
ASSERT_EQ(mymap.at(1), "voronoi1");
fonte
2012-08-15 15:43:58
Questo non è esattamente un duplicato, ma vedere qui: http://stackoverflow.com/questions/461507/how-to-use-boostforeach-with-a-boostptrmap/461908 # 461908 –