[英]Send member function pointer as parameter within another member function
I want to send a member function as a parameter, but it won't compile. 我想发送一个成员函数作为参数,但它不会编译。 Why doesn't the code work?
为什么代码不起作用? Here what I have written.
这就是我写的。 If I pass a lambda instead it works though.
如果我通过一个lambda而不是它有效。
void global_func(std::function<void(void)>f)
{
f();
}
class goo
{
public:
goo() { }
void func1()
{
std::function<void(void)> fp = &goo::func2; // get a pointer to the function func2 . Error here or next line
global_func( fp);
}
void func2(void)
{
}
};
void main()
{
goo g1;
g1.func1();
}
Here the compiler output ( my program name is tryvector.cpp) 这里编译输出(我的程序名是tryvector.cpp)
1>------ Build started: Project: TryVector, Configuration: Debug Win32 ------
1> TryVector.cpp
1>e:\program files\microsoft visual studio 12.0\vc\include\functional(506): error C2664: 'void std::_Func_class<_Ret,>::_Set(std::_Func_base<_Ret,> *)' : cannot convert argument 1 from '_Myimpl *' to 'std::_Func_base<_Ret,> *'
1> with
1> [
1> _Ret=void
1> ]
1> Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast
1> e:\program files\microsoft visual studio 12.0\vc\include\functional(442) : see reference to function template instantiation 'void std::_Func_class<_Ret,>::_Do_alloc<_Myimpl,_Fret(__thiscall goo::* const &)(void),_Alloc>(_Fty,_Alloc)' being compiled
1> with
1> [
1> _Ret=void
1> , _Fret=void
1> , _Alloc=std::allocator<std::_Func_class<void,>>
1> , _Fty=void (__thiscall goo::* const &)(void)
1> ]
1> e:\program files\microsoft visual studio 12.0\vc\include\functional(442) : see reference to function template instantiation 'void std::_Func_class<_Ret,>::_Do_alloc<_Myimpl,_Fret(__thiscall goo::* const &)(void),_Alloc>(_Fty,_Alloc)' being compiled
1> with
1> [
1> _Ret=void
1> , _Fret=void
1> , _Alloc=std::allocator<std::_Func_class<void,>>
1> , _Fty=void (__thiscall goo::* const &)(void)
1> ]
1> e:\program files\microsoft visual studio 12.0\vc\include\functional(442) : see reference to function template instantiation 'void std::_Func_class<_Ret,>::_Reset_alloc<_Fret,goo,,std::allocator<std::_Func_class<_Ret,>>>(_Fret (__thiscall goo::* const )(void),_Alloc)' being compiled
1> with
1> [
1> _Ret=void
1> , _Fret=void
1> , _Alloc=std::allocator<std::_Func_class<void,>>
1> ]
1> e:\program files\microsoft visual studio 12.0\vc\include\functional(442) : see reference to function template instantiation 'void std::_Func_class<_Ret,>::_Reset_alloc<_Fret,goo,,std::allocator<std::_Func_class<_Ret,>>>(_Fret (__thiscall goo::* const )(void),_Alloc)' being compiled
1> with
1> [
1> _Ret=void
1> , _Fret=void
1> , _Alloc=std::allocator<std::_Func_class<void,>>
1> ]
1> e:\program files\microsoft visual studio 12.0\vc\include\functional(671) : see reference to function template instantiation 'void std::_Func_class<_Ret,>::_Reset<void,goo,>(_Fret (__thiscall goo::* const )(void))' being compiled
1> with
1> [
1> _Ret=void
1> , _Fret=void
1> ]
1> e:\program files\microsoft visual studio 12.0\vc\include\functional(671) : see reference to function template instantiation 'void std::_Func_class<_Ret,>::_Reset<void,goo,>(_Fret (__thiscall goo::* const )(void))' being compiled
1> with
1> [
1> _Ret=void
1> , _Fret=void
1> ]
1> d:\vc++ my files\tryvector\tryvector\tryvector.cpp(42) : see reference to function template instantiation 'std::function<void (void)>::function<void(__thiscall goo::* )(void)>(_Fx &&)' being compiled
1> with
1> [
1> _Fx=void (__thiscall goo::* )(void)
1> ]
1> d:\vc++ my files\tryvector\tryvector\tryvector.cpp(42) : see reference to function template instantiation 'std::function<void (void)>::function<void(__thiscall goo::* )(void)>(_Fx &&)' being compiled
1> with
1> [
1> _Fx=void (__thiscall goo::* )(void)
1> ]
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
A std::function<void(void)>
is something which can just be called, without any parameters and without any further context. std::function<void(void)>
是可以被调用的东西,没有任何参数,也没有任何进一步的上下文。
goo:func2
, however, is a non-static member function. goo:func2
然而, goo:func2
是一个非静态成员函数。 It cannot just be called; 它不能被称为; it needs a
goo
instance . 它需要一个
goo
实例 。 It's as if it had an invisible parameter: void func2(goo* const this)
. 就好像它有一个不可见的参数:
void func2(goo* const this)
。 And that makes sense, because func2
probably needs some other non-static goo
members to do its job. 这是有道理的,因为
func2
可能需要一些其他非静态goo
成员来完成它的工作。
You have several options: 你有几个选择:
this
, ie: auto const fp = [this] { func2(); };
this
,即: auto const fp = [this] { func2(); };
auto const fp = [this] { func2(); };
. auto const fp = [this] { this->func2(); };
auto const fp = [this] { this->func2(); };
auto const fp = [this] { this->func2(); };
. func2
doesn't need any non-static members of goo
, then make the function static
. func2
不需要goo
任何非静态成员,那么使该函数为static
。 std::bind
. std::bind
。 A member function pointer cannot be wrapped into a std::function<void(void)>
because the member function has an implicit argument: The pointer this
. 成员函数指针不能包装到
std::function<void(void)>
因为成员函数有一个隐式参数:指针this
。 But the function wrapper you have defined only takes nullary callables. 但是你定义的函数包装器只需要使用nullary callables。
Solution 1: Change the function wrapper to std::function<void(goo*)>
. 解决方案1:将函数包装器更改为
std::function<void(goo*)>
。 This will require you to modify global_func
as well to pass the argument. 这将要求您修改
global_func
以传递参数。
Solution 2: Use std::bind
to generate a functor where the implicit pointer is bound to some instance. 解决方案2:使用
std::bind
生成一个仿函数,其中隐式指针绑定到某个实例。
It's because the member function does not have a matching signature. 这是因为成员函数没有匹配的签名。 It also contains implicit
this
. 它还包含隐含
this
。 You can make your example by binding the member function and this
: 您可以通过绑定的成员函数,使您的例子
this
:
#include <functional>
void global_func(std::function<void(void)>f)
{
f();
}
class goo
{
public:
goo() { }
void func1()
{
std::function<void(void)> fp = std::bind(&goo::func2, this);
global_func( fp);
}
void func2(void) { }
};
int main()
{
goo g1;
g1.func1();
}
Lambda works, because it can capture this
. Lambda工作,因为它可以捕获
this
。
Static function also would work, because it doesn't have implicit this
parameter. 静态函数也可以工作,因为它没有隐式的
this
参数。
Basically you need an instance on which behalf you call the functions, so in your case this
seems reasonable. 基本上你需要一个代表你调用函数的实例,所以在你的情况下
this
似乎是合理的。
Member functions have an implicit this
parameter as their first parameter. 成员函数将隐式
this
参数作为其第一个参数。
goo::func2(void)
is actually 实际上是
goo::func2(goo* const this);
You can do one of two things: 你可以做以下两件事之一:
Change the signature of global_func
to accept a type of std::function<void(goo*)>
更改
global_func
的签名以接受std::function<void(goo*)>
Use std::bind
to bind the this
parameter. 使用
std::bind
绑定this
参数。
std::function<void(void)> fp = std::bind(&goo::func2, this);
global_func(fp);
Your need either to make func2
a static class member function, or bind it to this
when you convert it to a std::function
: 您需要将
func2
设为静态类成员函数,或者在将其转换为std::function
时将其绑定this
std::function
:
std::function<void()> fp = std::bind(&goo::func2, this);
Some more -- There are a few other unusual constructs in your code. 更多 - 您的代码中还有一些其他不寻常的结构。 Although they work, but they are not good C++ practice:
虽然它们有效,但它们并不是很好的C ++实践:
void func2(void)
this is C Style, in C++ you just write void func2()
. 这是C Style,在C ++中你只需编写
void func2()
。 Also: 也:
void global_func(std::function<void()>f) // <-- not void(void)
Finally, int main()
not void main()
最后,
int main()
不是void main()
Because a non static member function is not a function. 因为非静态成员函数不是函数。 In common implementations, it includes a hidden pointer to the object on which it acts (
this
). 在通常的实现中,它包括一个指向它所作用的对象的隐藏指针(
this
)。
Only static methods can be used the same as functions. 只有静态方法可以与函数一样使用。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.