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

在类自身模板成员方法中获取类类型以取得成员函数指针的问题

解决方案

针对你遇到的两个核心问题,可以通过以下方式修改DECLARE_METHOD宏实现需求,且完全兼容原有使用方式:

1. 解决类内获取成员函数指针的编译错误

你遇到的编译报错是因为直接写&methodName_WRAPPER时,编译器会将其识别为绑定了当前this对象的成员函数引用,不符合成员函数指针的语法要求。我们可以通过decltype(*this)自动推导当前类的类型,无需手动传入类名:

  • 在模板函数内部使用std::remove_cvref_t<decltype(*this)>获取当前类的纯净类型(自动去除const、volatile、引用修饰符)
  • 基于推导的类类型拼接WRAPPER方法的完整成员函数指针

2. 实现WRAPPER方法私有且不影响后续作用域

由于你的DECLARE_METHOD生成的对外调用模板方法本身属于类的公共接口,默认应该放在类的public块中,我们可以在宏内手动切换访问权限:

  • 生成公共模板方法后,切换到private权限声明WRAPPER方法
  • 声明完成后切回public权限,保证后续类成员的默认访问权限和宏调用位置的预期一致

修改后的宏代码

你只需替换原有DECLARE_METHOD宏的定义即可:

#include <type_traits>

#define DECLARE_METHOD(ret_, func_, ...) \
    template <typename ... ARGS>\
    inline ret_ func_(ARGS&&... args) {\
        /* 自动推导当前类的类型,无需手动指定 */ \
        using ClassType = std::remove_cvref_t<decltype(*this)>; \
        return execute_later(this, &ClassType::func_##_WRAPPER, std::forward<ARGS>(args)...);\
    }\
    /* 切换到私有作用域声明WRAPPER */ \
    private:\
    ret_ func_##_WRAPPER(PARAMS_LOOP(__VA_ARGS__));\
    /* 切回public作用域,不影响后续代码 */ \
    public:

兼容性说明

如果使用的C版本低于C20,没有std::remove_cvref_t,可以替换为std::decay_t<decltype(*this)>,效果完全一致。

效果验证

修改后宏的展开效果完全符合预期:

// 你写的代码
class Test {
public:
    DECLARE_METHOD(int, methodName, (int, a) (AMoveOnlyType, b));
    // 后续的其他public成员不受影响
    int other_public_func();
};

// 宏展开后等效代码
class Test {
public:
    template <typename ... ARGS>
    inline int methodName(ARGS&&... args) {
        using ClassType = Test;
        return execute_later(this, &Test::methodName_WRAPPER, std::forward<ARGS>(args)...);
    }
private:
    int methodName_WRAPPER(int a, AMoveOnlyType b);
public:
    int other_public_func();
};
  • WRAPPER方法为私有,外部无法直接调用
  • 无需手动指定类名,完全兼容原有宏的使用方式
  • 编译错误彻底解决

内容的提问来源于stack exchange,提问作者Patrick Wright

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 08:54:04