почему он скомпилирован неправильно, когда я добавил ссылочный аргумент в функцию-член, которая является аргументом для std :: mem_fun ()? - PullRequest
3 голосов
/ 18 марта 2011

Во-первых, у меня был следующий фрагмент:

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

Он правильно скомпилирован. Но после того, как я изменил функцию-член incre на

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

выдает ошибки, как

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

У вас есть идеи о том, что происходит? Я буду признателен за любую помощь.

Ответы [ 2 ]

5 голосов
/ 18 марта 2011

Что происходит, так это то, что bind1st и mem_fun не работают со ссылками на всех платформах .

Вы можете использовать его с boost :: bind

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

и, казалось бы, GNU решила, что вышеприведенное - достаточно хороший обходной путь, чтобы пометить ошибку как "не исправленную".

В вашем случае вы можете передать по значению. Вы также можете с радостью передавать указатели на эти функции.

Кстати, то, что вы делаете, должно работать.

Передача по значению может и не исправить это, потому что вы вызываете неконстантную функцию-член. Также была проблема с неконстантными функциями-членами .

Ваша другая альтернатива, конечно, состоит в том, чтобы использовать std :: аккумулировать, а не std :: for_each, что подходит для этого конкретного случая, когда вы пробегаете свою коллекцию, генерирующую что-то. Я обычно предпочитаю использовать накопление:

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

, что позволяет избежать копирования «Результата» на каждой итерации. Здесь нет необходимости использовать bind1st или mem_fun, так что нет проблем, если вы передаете значение по ссылке.

4 голосов
/ 18 марта 2011

Проблема заключается в том, что внутренне mem_fun пытается установить в качестве типа аргумента константную ссылку на тип аргумента функции-члена. Если вы делаете функцию взятие ссылки, то она пытается создать ссылку на ссылку, что недопустимо в C ++. Это известный дефект в библиотеке, который исправляется новой функцией связывания, которая появится в C ++ 0x.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...