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
相关产品推荐
相关产品推荐

