Вопрос по loops, c++, stl, enumeration – Я использую это в пользовательском массиве, но он отлично работает и с std :: vector.

20

аружил, что пишу

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

и я бы тоже хотел переписать этого парня есть идеи?

О, также, по разным причинам, я не хочу использовать повышение.

Ваш Ответ

3   ответа
15
#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)
                 );
}
4

чтобы сделать то, что мне нужно:

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 (или стандартные функции связывания библиотеки) позволят вам связать параметр param с функцией, поэтому вам не нужно каждый раз указывать его в качестве аргумента.

boost :: lambda, пожалуй, самый лаконичный и гибкий подход. Я обычно использую простой функторный подход, потому что синтаксис легче запомнить. ;)

Это то, что я имел (и надеялся избежать) :) Jesse Beder
Хм, без повышения (ой), я не думаю, что вы можете сделать это намного короче. В некоторых случаях вам может помочь материал std :: bind_ *, но чудесных серебряных пуль нет. (По крайней мере, до c ++ 0x с добавлением лямбда-выражений) jalf
6

Правильное решение, но, скорее всего, неправильное. Рассмотрим Boost как расширение STL. C ++ - это язык, управляемый библиотекой. Если вы не примете это во внимание, ваш код будет качественно хуже.

Покаstd::for_each здесь можно использовать отсутствие лямбда-выражений в C ++, пока C ++ 0x не сделает это утомительным. Я защищаю использованиеBoost.ForEach! Это делает этомного Полегче:

foreach (yourtype x, yourvec)
    if (x.IsOK())
        x.Whatever();
@jalf А как насчетне буду? Mateen Ulhaq
Увы, это не мое решение, использовать ли Boost. Jesse Beder
Могу сказать, что тыне может используйте повышение тогда. Сказать, что ты нехочу просто просит аргумент ...;) jalf

Похожие вопросы