![](/img/trans.png)
[英]Passing a member function pointer to a non-member function within another member function
[英]Send member function pointer as parameter within another member function
我想发送一个成员函数作为参数,但它不会编译。 为什么代码不起作用? 这就是我写的。 如果我通过一个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();
}
这里编译输出(我的程序名是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 ==========
std::function<void(void)>
是可以被调用的东西,没有任何参数,也没有任何进一步的上下文。
goo:func2
然而, goo:func2
是一个非静态成员函数。 它不能被称为; 它需要一个goo
实例 。 就好像它有一个不可见的参数: void func2(goo* const this)
。 这是有道理的,因为func2
可能需要一些其他非静态goo
成员来完成它的工作。
你有几个选择:
this
,即: auto const fp = [this] { func2(); };
auto const fp = [this] { func2(); };
。 记住,这等于auto const fp = [this] { this->func2(); };
auto const fp = [this] { this->func2(); };
。 func2
不需要goo
任何非静态成员,那么使该函数为static
。 std::bind
。 成员函数指针不能包装到std::function<void(void)>
因为成员函数有一个隐式参数:指针this
。 但是你定义的函数包装器只需要使用nullary callables。
解决方案1:将函数包装器更改为std::function<void(goo*)>
。 这将要求您修改global_func
以传递参数。
解决方案2:使用std::bind
生成一个仿函数,其中隐式指针绑定到某个实例。
这是因为成员函数没有匹配的签名。 它还包含隐含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工作,因为它可以捕获this
。
静态函数也可以工作,因为它没有隐式的this
参数。
基本上你需要一个代表你调用函数的实例,所以在你的情况下this
似乎是合理的。
成员函数将隐式this
参数作为其第一个参数。
goo::func2(void)
实际上是
goo::func2(goo* const this);
你可以做以下两件事之一:
更改global_func
的签名以接受std::function<void(goo*)>
使用std::bind
绑定this
参数。
std::function<void(void)> fp = std::bind(&goo::func2, this);
global_func(fp);
您需要将func2
设为静态类成员函数,或者在将其转换为std::function
时将其绑定this
std::function
:
std::function<void()> fp = std::bind(&goo::func2, this);
更多 - 您的代码中还有一些其他不寻常的结构。 虽然它们有效,但它们并不是很好的C ++实践:
void func2(void)
这是C Style,在C ++中你只需编写void func2()
。 也:
void global_func(std::function<void()>f) // <-- not void(void)
最后, int main()
不是void main()
因为非静态成员函数不是函数。 在通常的实现中,它包括一个指向它所作用的对象的隐藏指针( this
)。
只有静态方法可以与函数一样使用。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.