CRTP模式下将成员函数指针转换为std::function遇编译错误
问题分析与解决
编译错误的核心原因是基类中的this类型与成员函数指针的所属类不匹配:
- 在
Base<Derived>中,this的类型是Base<Derived>* - 你传递的成员函数指针是
void (Derived::*)(),属于Derived类
std::bind_front将这两个类型绑定后生成的可调用对象,无法直接转换为std::function<void()>——因为调用该绑定对象时,需要将Base<Derived>*转换为Derived*才能调用Derived的成员函数,而bind_front不会自动完成这个类型转换。
修正后的代码
#include <functional> static void runIt(std::function<void()> f) { f(); } template<typename T> struct Base { using PFn = void (T::*)(); void run(PFn fun) { // CRTP模式下,将基类this安全转换为派生类指针 runIt(std::bind_front(fun, static_cast<T*>(this))); } }; struct Derived : Base<Derived> { void main() { run(&Derived::func); } void func() {} };
关键说明
你这里使用的是CRTP(奇异递归模板模式),Derived继承自Base<Derived>,因此static_cast<T*>(this)是完全安全的:this实际指向的是Derived对象的基类子对象,转换为Derived*属于合法的向上类型转换。绑定后的可调用对象现在能正确匹配成员函数指针的类型,自然可以顺利转换为std::function<void()>。
内容的提问来源于stack exchange,提问作者Alex O
相关产品推荐
相关产品推荐

