2

VS2008 SP1文档讨论了std::tr1::mem_fun.

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

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

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

这是我试图编译的示例代码,它应该通过 a调用TakesInt的实例:Testfunction<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's 来解决mem_fun。那是你的 C++ 编译器错误(或者可能只是我!)。


更新:对。答案是正确拼写为 mem_fn!

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

这是编译器错误:

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

3 回答 3

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);
于 2008-11-16T15:17:01.593 回答
2

我不是 TR1 或 VS2008 的专家,但快速谷歌搜索表明您正在寻找的功能是 std::tr1::mem_fn 。(至少,这就是 Boost 在他们的TR1 实现中所说的,这就是它在Wikipedia上的详细说明。)

不过,我不确定为什么旧版本的 mem_fun 会出现编译错误。如果您发布编译器关于此的消息,它可能会帮助我们弄清楚。

于 2008-11-16T13:35:21.393 回答
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);
于 2008-11-16T13:40:28.683 回答