更简单的方法是为矢量(或者STL中的其他东西)做回调吗? C ++

时间:2010-01-22 09:08:47

标签: c++ stl vector

我正在制作一个简单的犯罪模拟游戏。

在整个过程中,我一遍又一遍地做同样的事情:

// 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。

5 个答案:

答案 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指向的类的实例上创建一个调用sellthis的成员函数的函子,并将_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作为替代方案。