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

C++连接管理类代码去重咨询:无需为每个函数生成包装器

消除双连接操作的代码重复方案

这是个非常典型的重复代码优化场景,既然咱们不能修改m_conn这个连接对象,那可以利用C++的模板抽象或者函数对象来把重复的执行逻辑抽出来,不用为每个操作单独写包装器。下面给你两种实用的思路:

方案一:模板+成员函数指针(简洁高效)

核心思路是把「调用prepare方法 + commit」这个重复流程封装成一个通用模板函数,然后把具体的prepare方法(比如prepare_init、prepare_update)作为参数传进去。

实现代码:

首先在mngr类里添加一个通用的成员模板函数:

#include <functional> // 用于std::invoke(C++17及以上)

template<typename PrepareFunc, typename... Args>
void run_on_both_connections(PrepareFunc&& prepare_func, Args&&... args) {
    // 处理source连接
    std::invoke(std::forward<PrepareFunc>(prepare_func), m_conn, source_id, std::forward<Args>(args)...);
    m_conn.commit();
    
    // 处理target连接
    std::invoke(std::forward<PrepareFunc>(prepare_func), m_conn, target_id, std::forward<Args>(args)...);
    m_conn.commit();
}

然后原来的两个方法就可以简化成一行代码:

void mngr::init_conn(int var1, int var2, int var3) {
    run_on_both_connections(&ConnType::prepare_init, var1, var2, var3);
}

void mngr::update_conn(int var1, int var2) {
    run_on_both_connections(&ConnType::prepare_update, var1, var2);
}

注:ConnType是m_conn的实际类型,你需要替换成你代码里的类名。如果用的是C++17之前的标准,可以把std::invoke换成直接调用成员指针:(m_conn.*prepare_func)(source_id, std::forward<Args>(args)...)

这个方案的优点是代码极度简洁,编译期就能完成绑定,性能没有额外开销,完全适合参数完全一致的场景。

方案二:Lambda表达式(灵活适配特殊场景)

如果后续遇到某个操作需要给source和target传不同的参数(比如某个参数在target上要微调),用lambda的方式会更灵活。同样先封装通用执行流程:

实现代码:

template<typename ConnectionOp>
void run_on_both_connections(ConnectionOp&& op) {
    // 执行source端操作
    op(source_id);
    m_conn.commit();
    
    // 执行target端操作
    op(target_id);
    m_conn.commit();
}

然后调用时用lambda封装具体的prepare调用:

void mngr::init_conn(int var1, int var2, int var3) {
    run_on_both_connections([this, var1, var2, var3](int conn_id) {
        m_conn.prepare_init(conn_id, var1, var2, var3);
    });
}

// 如果哪天需要给target传不同的var3,直接改lambda就行:
void mngr::special_init_conn(int var1, int var2, int var3) {
    run_on_both_connections([this, var1, var2, var3](int conn_id) {
        int actual_var3 = (conn_id == target_id) ? var3 + 1 : var3;
        m_conn.prepare_init(conn_id, var1, var2, actual_var3);
    });
}

这个方案的优点是灵活性拉满,能处理任何参数不一致的特殊情况,可读性也很好,一眼就能看到每个连接的具体操作。

总结

  • 如果所有操作的参数完全一致,优先用模板+成员函数指针,代码最简洁高效;
  • 如果有特殊场景需要调整参数,用Lambda表达式更适配。

两种方案都只需要写一次通用逻辑,后续新增操作时只需要调用这个通用函数即可,彻底消除重复代码。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 06:30:03