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

ぃ、小莉子 提交于 2019-12-23 20:22:48

问题


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.


回答1:


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.




回答2:


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.



来源:https://stackoverflow.com/questions/5349973/why-did-it-compile-errorly-when-i-added-a-reference-argument-to-a-member-functio

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!