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

C++20中如何让代理类自动调用对应原始类的同名同参函数?

在C++20中简化代理类的自动调用实现

问题场景

我有一个原始类Original和代理类Proxy,代理类的每个成员函数需要添加日志、条件检查等额外逻辑,同时调用原始类的同名同参函数。当前实现需要手动传入原始类的函数指针和参数,希望在C++20中实现仅调用call()就能自动完成对应原始函数的调用,无需手动指定函数名和参数。

当前代码实现:

class Original {
public:
    void function1(int a) {
        // Implementation of function1
    }

    int function2(double b) {
        // Implementation of function2
    }

    // More functions...
};

class Proxy {
private:
    Original original;

public:
    template <typename Func, typename... Args>
    auto call(Func func, Args&&... args) -> decltype((original.*func)(std::forward<Args>(args)...)) {
        return (original.*func)(std::forward<Args>(args)...);
    }

    void function1(int a) {
        //Do some condition check and logging

        call(&Original::function1, a);

        //Do some condition check and logging
    }

    void function2(double b) {
        //Do some condition check and logging

        call(&Original::function2, b);

        //Do some condition check and logging
    }

    // More functions...
};

解决方案

C++20尚未支持完整的编译时反射,无法实现完全无需指定函数名的call()调用,但可以通过宏封装或模板辅助大幅简化代码,避免重复编写函数指针和参数传递逻辑。

方案一:宏封装自动生成代理函数

通过宏批量生成代理类成员函数,自动完成日志逻辑和原始函数调用,仅需一行宏调用即可完成:

#include <functional> // 用于std::invoke

class Original {
public:
    void function1(int a) {
        // 原始函数实现
    }

    int function2(double b) {
        // 原始函数实现
        return static_cast<int>(b * 2);
    }

    // 更多函数...
};

class Proxy {
private:
    Original original;

    // 通用call方法,封装原始函数调用逻辑
    template <auto Func, typename... Args>
    decltype(auto) call(Args&&... args) {
        return std::invoke(Func, original, std::forward<Args>(args)...);
    }

public:
    // 定义宏:自动生成带日志逻辑的代理函数
    #define DEFINE_PROXY_FUNC(ret_type, func_name, ...) \
    ret_type func_name(__VA_ARGS__) { \
        // 前置日志/条件检查逻辑 \
        call<&Original::func_name>(__VA_ARGS__); \
        // 后置日志/条件检查逻辑 \
    }

    // 生成代理函数
    DEFINE_PROXY_FUNC(void, function1, int a)
    DEFINE_PROXY_FUNC(int, function2, double b)

    // 取消宏定义,避免污染全局命名空间
    #undef DEFINE_PROXY_FUNC

    // 更多函数...
};

方案二:C++20模板与自动参数推导

如果不想使用宏,可以借助C++20模板特性简化参数传递,仅需指定一次原始函数指针:

#include <functional>

class Original {
public:
    void function1(int a) { /* ... */ }
    int function2(double b) { /* ... */ return 0; }
};

class Proxy {
private:
    Original original;

    // 模板化call方法,自动推导参数类型
    template <auto Func, typename... Args>
    decltype(auto) call(Args&&... args) {
        return std::invoke(Func, original, std::forward<Args>(args)...);
    }

public:
    void function1(int a) {
        // 前置日志/检查逻辑
        call<&Original::function1>(a);
        // 后置日志/检查逻辑
    }

    int function2(double b) {
        // 前置日志/检查逻辑
        auto result = call<&Original::function2>(b);
        // 后置日志/检查逻辑
        return result;
    }
};

说明

  • 宏封装方案是当前最简洁的实现方式,彻底避免了重复编写函数指针和参数的冗余代码。
  • 模板方案保留了手动指定函数指针的步骤,但通过std::invoke统一了成员函数调用逻辑,简化了参数传递写法。
  • 完整的编译时反射支持需等待C23及后续标准的进一步完善,当前C20无法实现完全无参数的call()自动匹配。

内容的提问来源于stack exchange,提问作者suresh kumar

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 07:44:56