简体   繁体   中英

why did it compile errorly when i added a reference argument to a member function which is the argument to std::mem_fun()?

Firstly, I had a snippet as following:

struct D
{

  int sum;

  D():sum(0){accum();}

  void incre(int arg){sum+=arg;}

  void accum()
  {
    int arr[]={1,2,3,4,5};

    std::for_each(arr,arr+ sizeof(arr)/sizeof(int),
                  std::bind1st(std::mem_fun(&D::incre),this));

    cout << sum <<endl;
  }
};

int main()
{
  D();
}

It compiled properly.But after my changing the member function incre to

void incre(int &  arg){sum+=arg;}

it produced errors, like

typename _Operation::result_type std::binder1st<_Operation>::operator()
    (typename _Operation::second_argument_type&) const [with _Operation = 
    std::mem_fun1_t<void, D, int&>]’ cannot be overloaded

Do you have any ideas about what is going on? I'll appreciate any help.

What is going on is that bind1st and mem_fun do not work with references on all platforms .

You can use it with boost::bind

std::for_each( arr, arr + sizeof(arr)/sizeof(int), 
   boost::bind( &D::incre, this, _1 ) );

and it would seem GNU have decided the above is a good enough workaround to mark the bug as "won't fix".

In your case you could pass in by value. You can also happily pass pointers into these functions.

What you are doing should work, by the way.

Passing by value might not fix it either because you are calling a non-const member function. There was an issue also about non-const member functions .

Your other alternative of course is to use std::accumulate rather than std::for_each, which is suitable for this particular case where you are running through your collection generating something. The way I generally prefer to use accumulate is:

Result r;
Result* binaryfunc( Result*, T value ); // returns the same pointer passed in
std::accumulate( coll.begin(), coll.end(), binaryfunc, &r );

which avoids copying the "Result" on every iteration. There is no need to use bind1st or mem_fun here so no issue either if you are passing in value by reference.

The problem is that internally, mem_fun tries to set as its argument type a const reference to the argument type of the member function. If you make then function take in a reference, then it tries to create a reference to a reference, which is illegal in C++. This is a known defect in the library and is being remedied by the new bind function that will appear in C++0x.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM