You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 12:40:50