문제

나는 나 자신이 글을 발견했다

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 ++ 0X까지 C ++에 Lambda 표현이 없으면이 지루하게 만들 수 있습니다. 나는 사용을 옹호한다 boost.foreach! 이것은 이것을 만듭니다 많이 더 쉬운 :

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

내가 선호하는 솔루션은 일반적으로 내가 필요한 것을 수행하기 위해 untictor를 작성하는 것입니다.

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));

이것의 얼마나 많은 변형에 따라, 이것은 너무 장황 할 수 있습니다. 그래도 인라인을 수행하기위한 많은 옵션이 있습니다. Boost :: Lambda를 사용하면 콜 사이트에서 필요한 기능을 구성 할 수 있습니다. boost :: bind (또는 표준 라이브러리 바인드 함수)를 사용하면 매개 변수를 함수에 바인딩 할 수 있으므로 매번 인수로 제공 할 필요가 없습니다.

Boost :: Lambda는 아마도 가장 간결하고 유연한 접근 방식 일 것입니다. 구문은 기억하기 쉽기 때문에 보통 일반 Functor 접근 방식을 사용합니다. ;)

C ++ 0X Lambda 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