如何在Visual Studio 2008 SP1中使用std :: tr1 :: mem_fun?

时间:2008-11-16 11:38:50

标签: c++ std tr1 mem-fun

VS2008 SP1 文档介绍 std::tr1::mem_fun

为什么,当我尝试使用 std::tr1::mem_fun 时,为什么会出现此编译错误?:

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

与此同时,我可以毫无问题地使用 std::tr1::function

以下是我尝试编译的示例代码,它应该通过TakesIntTest的实例上调用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);
}

我正在尝试使用 mem_fun 的tr1版本,因为在使用 std::mem_fun 时,我的代码也无法编译!我无法从编译器错误中判断问题是否与我的代码有关,或者是否可以通过使用tr1的 mem_fun 来解决。那是你的C ++编译器错误(或者也许只是我!)。

<小时/>

更新:对。答案是将其拼写为mem_fn!

然而,当我修复它时,代码仍然无法编译。

这是编译器错误:

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

3 个答案:

答案 0 :(得分:3)

将其更改为:

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

binder需要int参数。所以你必须给它一个占位符,它代表生成的函数对象需要的整数参数。

顺便说一下:我不确定你是否已经知道这一点。但是你不需要那个mem_fn。只需将其更改为

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

答案 1 :(得分:2)

我不是TR1或VS2008的专家,但是快速的谷歌搜索表明你正在寻找的函数是std :: tr1 :: mem_fn。 (至少,这就是Boost在他们的TR1 implementation中所称的内容,而这就是Wikipedia上的详细内容。)

我不知道你为什么会在旧版本的mem_fun中遇到编译错误。如果你发布编译器关于它的消息,它可能有助于我们解决它。

答案 2 :(得分:1)

要像这样使用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);