【发布时间】:2010-08-02 17:52:15
【问题描述】:
我想把这个结果:
std::tr1::mem_fn(&ClassA::method);
在一个变量里面,这个变量的类型是什么?
看起来像这样:
MagicalType fun = std::tr1::mem_fn(&ClassA::method);
另外,std::tr1::bind 的结果类型是什么?
谢谢!
【问题讨论】:
我想把这个结果:
std::tr1::mem_fn(&ClassA::method);
在一个变量里面,这个变量的类型是什么?
看起来像这样:
MagicalType fun = std::tr1::mem_fn(&ClassA::method);
另外,std::tr1::bind 的结果类型是什么?
谢谢!
【问题讨论】:
std::tr1::mem_fn 和 std::tr1::bind 的返回类型均未指定。
您可以将std::tr1::bind 的结果存储在std::tr1::function 中:
struct ClassA {
void Func() { }
};
ClassA obj;
std::tr1::function<void()> bound_memfun(std::tr1::bind(&ClassA::Func, obj));
您还可以将std::tr1::mem_fn 的结果存储在std::tr1::function 中:
std::tr1::function<void(ClassA&)> memfun_wrap(std::tr1::mem_fn(&ClassA::Func));
【讨论】:
std::tr1::function<void(MyType*)> fun = std::tr1::mem_fn(&ClassA::method);,但它无法编译,这是怎么回事?
mem_fn 返回的可调用对象接受引用,而不是指针。查看更新的答案。
function<void(ClassA&, MyType*)>。
mem_fn 和bind 的返回类型是未指定。这意味着,根据参数返回不同类型的对象,并且标准没有规定必须如何实现此功能的细节。
如果您想通过特定的库实现找出特定情况下的类型(我希望出于理论上的兴趣),您总是会导致错误,并从错误消息中获取类型。例如:
#include <functional>
struct X
{
double method(float);
};
int x = std::mem_fn(&X::method);
9 Untitled.cpp cannot convert 'std::_Mem_fn<double (X::*)(float)>' to 'int' in initialization
在这种情况下,请注意类型名称保留供内部使用。在您的代码中,您不应该使用带有前导下划线(和大写字母)的任何内容。
在 C++0x 中,我想返回类型是 auto :)
auto fun = std::mem_fn(&ClassA::method);
【讨论】:
该函数可以通过以下方式实现(因此您也可以看到返回类型):您可以在http://webcompiler.cloudapp.net/ 尝试这段代码。不幸的是,它使用了可变参数模板 https://en.wikipedia.org/wiki/Variadic_template,这只是 C++11 标准的一部分。
#include <iostream>
#include <string>
template <class R, class T, class... Args > class MemFunFunctor
{
private:
R (T::*mfp)(Args... ); //Pointer to a member function of T which returns something of type R and taking an arbitrary number of arguments of any type
public:
explicit MemFunFunctor(R (T::*fp)(Args... ) ):mfp(fp) {}
R operator()(T* t, Args... parameters)
{
(t->*mfp)(parameters... );
}
};
template <class R,class T, class... Args> MemFunFunctor<R,T,Args... > my_mem_fn( R (T::*fp)(Args... ) )
{
return MemFunFunctor<R,T,Args... >(fp);
}
class Foo //Test class
{
public:
void someFunction(int i, double d, const std::string& s )
{
std::cout << i << " " << d << " " << s << std::endl;
}
};
int main() //Testing the above code
{
Foo foo;
auto f = my_mem_fn(&Foo::someFunction);
f(&foo, 4, 6.7, "Hello World!" ); //same as foo.someFunction(4, 6.7, "Hello World!");
return 0;
}
【讨论】: