我正在制作一个简单的犯罪模拟游戏。
在整个过程中,我一遍又一遍地做同样的事情:
// vector<Drug*> drugSack;
for (unsigned int i = 0; i < this->drugSack.size(); i++)
this->sell(drugSack[i]);
只是一个例子。我讨厌所有这些for循环在整个地方omg QQ,无论如何做类似的事情:
drugSack->DoForAll((void*)myCallBack);
我不太熟悉STL。
答案 0 :(得分:8)
开始了解stl算法的时间:
#include <algorithm>
...
std::for_each( drugSack.begin(), drugSack.end(),
std::bind1st( std::mem_fun_ptr( &ThisClass::Sell ), this ) );
我们的想法是创建一个称为“仿函数”的对象,该对象可以对drugSack.begin(), drugSack.end()
范围内的每个元素执行特定操作。
这个仿函数可以使用像mem_fun_ptr
这样的stl结构创建,从而使得一个仿函数采用ThisClass*
和一个Drug*
参数,以及一个包装它的包装器将替换/绑定{ {1}} Class*
。
答案 1 :(得分:5)
老实说,C ++目前在这种方面非常糟糕。它确实可以做到,正如xtofl的回答所述,但它通常非常笨拙。
Boost有一个非常方便的for-each macro:
#include <boost/foreach.hpp>
#define foreach BOOST_FOREACH
// ...
foreach(Drug* d, drugSack)
{
sell(d);
}
或许Boost.Bind,虽然这稍微复杂一点,但对于你的情况来说它非常好看:
#include <boost/bind.hpp>
// ...
// ThisClass refers to whatever class this method is in
std::for_each(drugSack.begin(), drugSack.end(),
boost::bind(&ThisClass::sell, this, _1));
Bind会在ThisClass
指向的类的实例上创建一个调用sell
,this
的成员函数的函子,并将_1
替换为for_each
它来自std::for_each(drugSack.begin(), drugSack.end(),
[this](DrugSack* d){ sell(d); });
的论据。
最常用的方法是使用lambda。 Boost有一个lambda library。我不会包括 这里的示例是因为对于你的特定情况,boost绑定有效,而lambda将是相同的代码。那就是说,兰巴可以做得更多!它们基本上创建了就地函数(作为仿函数实现),但学习起来要复杂得多。
在我看来,for-each和bind都比“标准”C ++方法更清晰。现在,我建议按顺序:for-each,bind,标准C ++,lambda's。
在C ++ 0x中,下一个C ++标准,所有这一切都会很好,内置lambda支持:
for(DrugSack* d : drugSack)
{
sell(d);
}
或新的基于范围的for循环:
this->
但是我们必须等待几年才可以选择。 :(另外,我认为基于范围的for循环是最容易阅读的。这就是为什么我建议使用boost for-each,因为它模仿了这种行为和语法(主要是)。
另外,完全不相关:根据我的经验,在所有内容之前包含{{1}}的样式通常被视为不良实践。编译器会为你做这件事,你所做的只是弄乱你的代码并引入错误的机会。没有它,事情就会好得多。
答案 2 :(得分:2)
您可以使用STL中的std :: for_each将函数应用于范围。请参阅以下说明:http://www.cplusplus.com/reference/algorithm/for_each/。
您还需要使用std :: mem_fun或std :: mem_fun_ptr来获取您班级的成员函数。
对于更高级的案例,请查看Boost Bind,它提供了用于创建函数对象的高级绑定器。
答案 3 :(得分:1)
好吧,首先我很困惑:什么是sell
?它是否意味着成为某个类的成员函数,你需要make drugSack那个类,在这种情况下你可以做类似下面的事情 -
for_each
之类的内容可以迭代drugSack
,与mem_fun
结合使用sell
:
for_each(drugSack.begin(), drugSack.end(), mem_fun(&Drug::sell))
如果sell只是一个普通的函数,你可以把它放在for_each的第三个参数中。
答案 4 :(得分:1)
对于循环遍历整个容器的简单情况,我只是编写循环。不幸的是,这是啰嗦,但如果你总是以同样的方式写它,就不容易出错。我总是编写如下循环:
Container c;
for (Container::iterator i = c.begin(), end = c.end(); i != end; ++i)
...
(或const_iterator
)。
您可以尝试BOOST_FOREACH作为替代方案。