我有:
struct Mystruct
{
void Update(float Delta);
}
typedef std::map<int, Mystruct*> TheMap;
typedef TheMap::iterator TheMapIt;
TheMap Container;
并希望这样做:
for(TheMapIt It = Container.begin(), Ite = Container.end(); It != Ite; ++It)
{
It->second->Update(Delta);
}
使用std::for_each
,该怎么做?
我想我可以声明如下函数:
void Do(const std::pair<int, Mystruct*> Elem)
{
Elem->Update(/*problem!*/); ---> How to pass Delta in?
}
或制作另一个结构:
struct Doer
{
Doer(float Delta): d(Delta) {}
void operator(std::pair<int, Mystruct*> Elem)
{
Elem->Update(d);
}
}
但这需要一个新结构。
我想要实现的是使用普通的std::for_each
与std::bind_1st
,std::mem_fun
类似std::vector
的方式,是否可能?
在使用std
之前,请考虑使用boost
方式,谢谢!
我引用了这个,但它没有关于成员函数的输入... How would I use for_each to delete every value in an STL map?
答案 0 :(得分:6)
这只是编码风格之间的交易,for循环和for_each没有太大的区别,下面是除了循环之外的另外两种方法:
如果您使用C ++ 11,可以尝试lambda:
std::for_each(TheMap.begin(), TheMap.end(),
[](std::pair<int, Mystruct*>& n){ n.second->Update(1.0); });
或者在C ++ 03中,您可以向包装类添加成员函数,然后调用std::bind1st
和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));
写一个仿函数不是一个糟糕的选择,为什么你反对呢?仿函数提供了更好的设计,因为它提供了清晰明确的目的。
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);
答案 1 :(得分:2)
只是想指出lambda可以用更好的语法编写,你已经通过为你的地图定义一个typedef来开始这条道路。下一步是使用ValueType,这样你就不必记住map元素是std :: pairs,也避免写出模板参数。
using namespace std;
for_each(begin(Container), end(Container),
[](TheMap::ValueType& n){ n.second->Update(1.0); });
更容易阅读,并允许您更改一些细节,而无需在大量不同的地方传播这些更改。