Как использовать std::tr1::mem_fun в Visual Studio 2008 SP1?

Документация VS2008 SP1 говорит о std::tr1::mem_fun,

Так почему, когда я пытаюсь использовать std::tr1::mem_fun, почему я получаю эту ошибку компиляции?:

'mem_fun' : is not a member of 'std::tr1'

В то же время я могу использовать std::tr1::function без проблем.

Вот пример кода, который я пытаюсь скомпилировать, который должен вызвать TakesInt на примере Test через function<void (int)>:

#include "stdafx.h"
#include <iostream>
#include <functional>
#include <memory>

struct Test { void TakesInt(int i) { std::cout << i; } };

void _tmain() 
{
    Test* t = new Test();

    //error C2039: 'mem_fun' : is not a member of 'std::tr1'
    std::tr1::function<void (int)> f =
        std::tr1::bind(std::tr1::mem_fun(&Test::TakesInt), t);
    f(2);
}

Я пытаюсь использовать версию tr1 mem_fun потому что при использовании std::mem_fun мой код тоже не компилируется! Я не могу сказать по ошибке компилятора, связана ли проблема с моим кодом или она будет исправлена ​​с помощью tr1 mem_fun, Это ошибки компилятора C++ для вас (или, может быть, это только я!).


Обновление: верно. Ответ заключается в том, чтобы записать его правильно как mem_fn!

Однако, когда я исправляю это, код все еще не компилируется.

Вот ошибка компилятора:

error C2562: 
'std::tr1::_Callable_obj<_Ty,_Indirect>::_ApplyX' :
  'void' function returning a value

3 ответа

Решение

Измените это на это:

std::tr1::function<void (int)> f =
    std::tr1::bind(std::tr1::mem_fn(&Test::TakesInt), t, std::tr1::placeholders::_1);
f(2);

Связыватель требует аргумент int. Таким образом, вы должны дать ему заполнитель, который обозначает целочисленный аргумент, в котором нуждается сгенерированный объект функции.

Кстати: я не уверен, знаете ли вы это уже или нет. Но вам не нужен этот mem_fn для этого. Просто измените это на

std::tr1::function<void (int)> f =
    std::tr1::bind(&Test::TakesInt, t, std::tr1::placeholders::_1);
f(2);

Я не эксперт ни по TR1, ни по VS2008, но быстрый поиск в Google позволяет предположить, что функция, которую вы ищете, это std::tr1::mem_fn. (По крайней мере, так Boost называет это в своей реализации TR1, и именно так это подробно описано в Википедии.)

Я не уверен, почему вы получаете ошибку компиляции со старой версией mem_fun. Если вы опубликуете сообщение компилятора об этом, это может помочь нам разобраться в этом.

Чтобы использовать mem_fun таким образом, вам нужно полностью указать все аргументы шаблона (так как mem_fun является классом, и автоматическое удержание параметра шаблона не выполняется для классов). Кроме того, mem_fun имеет только конструктор по умолчанию, который принимает 0 аргументов.

Не имея полного определения класса, его трудно получить правильно.
Но моя лучшая ставка на то, что вы хотели, была бы такой: (или что-то близкое)

 std::tr1::mem_fun<Test,void (Test::*)(Test*),&Test::TakesInt>()

Я думаю, что вы ищете это mem_fn(). Это функция, которая возвращает объект типа mem_fun. Потому что это функция автоматического вывода параметров шаблона.

  std::tr1::mem_fn(&Test::TakesInt)

Для решения второй проблемы используйте: std::bind1st()

  f=    std::bind1st(std::tr1::mem_fn(&Test::TakesInt), t);
Другие вопросы по тегам