Как использовать std :: tr1 :: mem_fun в Visual Studio 2008 SP1? - PullRequest
2 голосов
/ 16 ноября 2008

В документации 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 ]

3 голосов
/ 16 ноября 2008

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

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);
2 голосов
/ 16 ноября 2008

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

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

1 голос
/ 16 ноября 2008

Чтобы использовать 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);
...