问题 使用std :: mem_fun时如何传递两个参数?


让我说我有这样的层次结构(这只是一个测试程序。请不要指出任何与内存泄漏相关的东西,析构函数不是虚拟的等):

class I
{
public:
    virtual void fun(int n, int n1) = 0;
};

class A : public I
{
public:
    void fun(int n, int n1)
    {
        std::cout<<"A::fun():" <<n<<" and n1:" <<n1<<"\n";
    }
};

class B : public I
{
public:
    void fun(int n, int n1)
    {
        std::cout<<"B::fun():" <<n<<" and n1:" <<n1<<"\n";
    }
};


int  main()
{
    std::vector<I*> a;
    a.push_back(new A);
    a.push_back(new B);

    //I want to use std::for_each to call function fun with two arguments.
}

如何调用fun()方法,该方法使用std :: for_each获取两个参数?我想我必须使用std :: mem_fun可能与std :: bind2nd,但我无法弄清楚如何做到这一点。任何线索如何实现这一目标?我没有使用提升。


9049
2018-06-22 12:40


起源

不使用boost意味着你没有tr1吗? - Todd Gardner


答案:


您可以像这样创建自己的仿函数:

class Apply
{
private:
  int arg1, arg2;

public:
  Apply(int n, int n1)
    : arg1(n), arg2(n1) 
  {}        

  void operator() (I* pI) const
  {
    pI->fun(arg1, arg2);
  }
};

int main ()
{
  // ...
  std::for_each(a.begin(), a.end(), Apply(n, n1));
}

或者像这样使用boost :: bind:

std::for_each(
  a.begin(),
  a.end(),
  boost::bind(&I::fun, _1, n, n1));

7
2018-06-22 12:52



我希望我能避免写一个仿函数。看起来就像没有出路一样。不是吗? - Naveen
我不知道是否有一种方法只使用stl,因为std :: mem_fun最多接受一个参数。 - Tobias


您无法使用标准粘合剂执行此操作。你当然可以编写自己的仿函数。

struct TwoArguments
{
   int one;
   int two;

   TwoArguments( int one, int two ) : one(one),two(two){
   }

   void operator()( I* i ) const {
       i->fun( one, two );
   }
};

4
2018-06-22 12:50





另一种方法是使用模板。 (请告诉我这是不好的做法!)

template<int N, int N1>
void Apply(I* i)
{
  i->fun(N, N1);
}

std::for_each(a.begin(), a.end(), Apply<firstParam, secondParam>);

如果你不打算用很多不同的参数调用它,这将是很好的,因为它会为你所做的每个组合生成代码。


1
2018-06-22 14:13



这很有趣..我从来没有想过像这样实现它。 - Naveen
但是这个解决方案只有在编译时知道参数N,N1才有效。你不能写std :: for_each(a.begin(),a.end(),Apply <getN(),getN1()>); - Tobias
你先生是对的 - Gab Royer