我发现自己写

for(int i=0;i<myvec.size();i++)
   myvec[i]->DoWhatever(param);

了很多,我想压缩成foreach声明这一点,但我不知道怎么去param在那里没有去超级冗长。我也得到了类似的事情。

for(int i=0;i<myvec.size();i++)
   if(myvec[i]->IsOK())
      myvec[i]->DoWhatever(param);

和我想重写那个家伙了。任何想法?

呵呵,也是,由于种种原因,我不想使用升压。

有帮助吗?

解决方案

#include <vector>
#include <algorithm>
#include <functional>

class X
{
    public:
        void doWhat(int x) {}
        bool IsOK() const {return true;}
};
class CallWhatIfOk
{
    public:
        CallWhatIfOk(int p): param(p) {}

        void operator()(X& x) const
        {   if (x.IsOK())    {x.doWhat(param);}}
    private:
        int param;
};

int main()
{
    std::vector<X>      myVec;

    std::for_each(  myVec.begin(),
                    myVec.end(),
                    std::bind2nd(std::mem_fun_ref(&X::doWhat),4)
                 );


    std::for_each(  myVec.begin(),
                    myVec.end(),
                    CallWhatIfOk(4)
                 );
}

其他提示

  

呵呵,也是,由于种种原因,我不想使用升压。

有效的决定,但最有可能错了。考虑升压作为扩展到STL。 C ++是一个库驱动的语言。如果不考虑到这一点,你的代码将定性逊色。

虽然std::for_each这里可以使用,由于没有在C ++ lambda表达式直到的C ++ 0x使得这种繁琐。我提倡使用 Boost.ForEach !它使这个的的简单:

foreach (yourtype x, yourvec)
    if (x.IsOK())
        x.Whatever();

我首选的方案通常是写一个函子做我需要:

struct doWhatever {
  doWhatever(const Param& p) p(p) {}
  void operator(MyVec v&, Param p) {
    v.DoWhatever(param);
  }

private:
  Param p;
};

和然后循环:

std::for_each(myvec.begin(), myvec.end(), doWhatever(param));

根据你有多少这样的变化有,这可能是有点太冗长。 有很多做它内嵌虽然选项。 提高::拉姆达将让你构建你需要在调用点的功能。提高::绑定(或标准库函数绑定)将让你的参数param绑定功能,所以你不需要每次都提供其作为一个参数。

的boost ::拉姆达可能是最简洁,最灵活的方式。我通常使用普通的仿函数的方法,因为语法更容易记住。 ;)

以及当我们有支持的C ++ 0x拉姆达expresions编译器,这成为直接和微创:

std::for_each(myvec.begin(),myvec.end(),[&](X& item){
     item->DoWhatever(param);
});

和第二个例子可以是这样的:

std::for_each(myvec.begin(),myvec.end(),[&](X& item){   
   if(item->IsOK())      
      myvec[i]->DoWhatever(param);
});
#include <vector>
#include <algorithm>
#include <boost/bind.hpp>
#include <boost/lambda/if.hpp>
#include <boost/lambda/bind.hpp>


struct A
{
  bool IsOK () { return true; }
  void DoWhatever (int param) {}
};

struct B
{
  bool IsOk (A * a) { return true; }
  void DoWhatever (A * a, int param) {}
};

typedef std::vector<A *> Myvec;

void main()
{
  Myvec myvec;
  int param = 1;
  B b;

  // first challenge using boost::bind (fnct in the same class)
  std::for_each (myvec.begin(), myvec.end(),
    boost::bind (&A::DoWhatever, _1, param));

  // first challenge using boost::bind (fnct in an external class)
  std::for_each (myvec.begin(), myvec.end(),
    boost::bind (&B::DoWhatever, &b, _1, param));

  // second challange using boost::lambda (fnct in the same class)
  std::for_each (myvec.begin(), myvec.end(),
    boost::lambda::if_then(
      boost::lambda::bind (&A::IsOK, boost::lambda::_1), 
      boost::lambda::bind (&A::DoWhatever, boost::lambda::_1, param)
    )
  );

  // second challange using boost::lambda (fnct in an external class)
  std::for_each (myvec.begin(), myvec.end(),
    boost::lambda::if_then(
      boost::lambda::bind (&B::IsOK, &b, boost::lambda::_1), 
      boost::lambda::bind (&B::DoWhatever, &b, boost::lambda::_1, param)
    )
  );

}

可以通过使用命名空间简化它...

如果你正在使用gcc,你可以定义是这样的:

#define foreach(element, array) \
    for(typeof((array).begin()) element = (array).begin(), __end_##element = (array).end();\
        element != __end_##element;\
        ++element)

和之后使用它是这样的:

foreach(element, array){
    element->DoSomething(); //or (*element)->DoSomething() if type is already a pointer
}

我用这个定制阵列上,但它工作正常的std ::矢量太

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top