How to use std::for_each on a map element method with input?

烂漫一生 提交于 2020-01-24 11:11:27

问题


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

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!