问题
I have:
struct Mystruct
{
void Update(float Delta);
}
typedef std::map<int, Mystruct*> TheMap;
typedef TheMap::iterator TheMapIt;
TheMap Container;
and wants to do:
for(TheMapIt It = Container.begin(), Ite = Container.end(); It != Ite; ++It)
{
It->second->Update(Delta);
}
using std::for_each
, how to do this?
I think I can declare function like:
void Do(const std::pair<int, Mystruct*> Elem)
{
Elem->Update(/*problem!*/); ---> How to pass Delta in?
}
Or make another struct:
struct Doer
{
Doer(float Delta): d(Delta) {}
void operator(std::pair<int, Mystruct*> Elem)
{
Elem->Update(d);
}
}
But this requires a new struct.
What I wants to achieve is using plain std::for_each
with something like std::bind_1st
, std::mem_fun
like the way with std::vector
, is it possible?
Please consider using std
way before using boost
, thanks!
I've referenced this but it doesnt metion about member function with input... How would I use for_each to delete every value in an STL map?
回答1:
This is just a trade between coding style, for loop and for_each doesn't make big difference, below are two other approaches besides for loop:
If you use C++11, could try lambda:
std::for_each(TheMap.begin(), TheMap.end(),
[](std::pair<int, Mystruct*>& n){ n.second->Update(1.0); });
Or in C++03, you could add a member function to wrapper class then call std::bind1st
and std::mem_fun
struct MapWrapper
{
MapWrapper(int value=1.0):new_value(value) {}
void Update(std::pair<int, Mystruct*> map_pair)
{
map_pair.second->Update(new_value);
}
void setValue(float value) { new_value = value; }
float new_value;
std::map<int, Mystruct*> TheMap;
};
MapWrapper wrapper;
wrapper.setvalue(2.0);
std::for_each(wrapper.TheMap.begin(),
wrapper.TheMap.end(),std::bind1st(std::mem_fun(&MapWrapper::Update), &wrapper));
Write a functor isn't a bad choice, why you are against it? A functor provides better design as it provides clean and clear purpose.
struct Doer
{
Doer(float Delta): d(Delta) {}
void operator()(std::pair<int, Mystruct*> e)
{
e.second->Update(d);
}
float d;
};
Doer doer(1.0);
std::for_each(wrapper.TheMap.begin(), wrapper.TheMap.end(), doer);
回答2:
Just wanted to point out the lambda can be written with nicer syntax, which you've already started down this road by defining a typedef for your map. The next step is to use ValueType so you don't have to remember that map elements are std::pairs, and also to avoid having to write out the template arguments.
using namespace std;
for_each(begin(Container), end(Container),
[](TheMap::ValueType& n){ n.second->Update(1.0); });
Much easier to read, and lets you change some details without necessarily having to propagate those changes a ton of different places.
来源:https://stackoverflow.com/questions/14037656/how-to-use-stdfor-each-on-a-map-element-method-with-input